Рейтинг@Mail.ru

Наши друзья и партнеры

UnixForum




Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Электронные книги по ОС Linux
Цилюрик О.И. Linux-инструменты для Windows-программистов
Назад Библиотеки API POSIX Вперед

Создание потока

Новый поток создаётся вызовом :

int pthread_create( pthread_t *newthread, const pthread_attr_t *attr,

void *(*start_routine)(void*), void *arg );

Все примеры кода для этой группы находятся в архиве upthread.tgz. Простейший пример (но на котором можно очень много увидеть из области работы с потоками) :

ptid.c :

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <pthread.h> 
void put_msg( char *title, struct timeval *tv ) { 
   printf( "%02u:%06lu : %s\t: pid=%lu, tid=%lu\n", 
           ( tv->tv_sec % 60 ), tv->tv_usec, title, getpid(), pthread_self() ); 
} 
void *test( void *in ) { 
   struct timeval *tv = (struct timeval*)in; 
   gettimeofday( tv, NULL ); 
   put_msg( "pthread started", tv ); 
   sleep( 5 ); 
   gettimeofday( tv, NULL ); 
   put_msg( "pthread finished", tv ); 
   return NULL; 
} 
#define TCNT 5 
static pthread_t tid[ TCNT ]; 
int main( int argc, char **argv, char **envp ) { 
   pthread_t tid[ TCNT ]; 
   struct timeval tm;. 
   int i;. 
   gettimeofday( &tm, NULL ); 
   put_msg( "main started", &tm ); 
   for( i = 0; i < TCNT; i++ ) { 
      int status = pthread_create( &tid[ i ], NULL, test, (void*)&tm );
         if( status != 0 ) perror( "pthread_create" ), exit( EXIT_FAILURE ); 
   }; 
   for( i = 0; i < TCNT; i++ )
      pthread_join( tid[ i ], NULL ); // это обычная техника ожидания!
   gettimeofday( &tm, NULL ); 
   put_msg( "main finished", &tm ); 
   return( EXIT_SUCCESS ); 
} 

В отличие от многих других UNIX, в Linux компиляция примеров с таким вызовом завершится ошибкой:

$ g++ ptid.cc -o ptid 

/tmp/ccnW2hnx.o: In function `main': 
ptid.cc:(.text+0x6e): undefined reference to `pthread_create' 
collect2: выполнение ld завершилось с кодом возврата 1 

Необходимо явное включение библиотеки libpthread.so в сборку:

$ ls /usr/lib/*pthr* 

/usr/lib/libgpgme-pthread.so.11      /usr/lib/libgpgme++-pthread.so.2.4.0 
/usr/lib/libgpgme-pthread.so.11.6.6  /usr/lib/libpthread_nonshared.a 
/usr/lib/libgpgme++-pthread.so.2     /usr/lib/libpthread.so 

В строку компиляции нужно дописать:

$ gcc ptid.c -lpthread -o ptid

Выполнение этого примера:

$ ./ptid 

50:259188 : main started	: pid=13745, tid=3079214784
50:259362 : pthread started	: pid=13745, tid=3079211888
50:259395 : pthread started	: pid=13745, tid=3068722032
50:259403 : pthread started	: pid=13745, tid=3058232176
50:259453 : pthread started	: pid=13745, tid=3047742320
50:259466 : pthread started	: pid=13745, tid=3037252464
55:259501 : pthread finished	: pid=13745, tid=3079211888
55:259501 : pthread finished	: pid=13745, tid=3068722032
55:259525 : pthread finished	: pid=13745, tid=3058232176
55:259532 : pthread finished	: pid=13745, tid=3047742320
55:259936 : main finished	: pid=13745, tid=3079214784 

Параметр (1-й) newthread вызова является адресом идентификатором создаваемого потока (куда будет возвращён идентификатор), типа pthread_t, определённого в </usr/include/bits/pthreadtypes.h>:

typedef unsigned long int pthread_t; /* Thread identifiers. */

Этот идентификатор принципиально отличается от идентификатора присваиваемого ядром, для которого предусмотрен вызов gettid() (показан вывод одновременно с выполнением примера выше):

$ ps -efL | grep ptid 

UID       PID  PPID   LWP  C NLWP STIME TTY          TIME CMD 
olej    13745  8859 13745  0    6 17:14 pts/10   00:00:00 ./ptid 
olej    13745  8859 13746  0    6 17:14 pts/10   00:00:00 ./ptid 
olej    13745  8859 13747  0    6 17:14 pts/10   00:00:00 ./ptid 
olej    13745  8859 13748  0    6 17:14 pts/10   00:00:00 ./ptid 
olej    13745  8859 13749  0    6 17:14 pts/10   00:00:00 ./ptid 
olej    13745  8859 13750  0    6 17:14 pts/10   00:00:00 ./ptid 

Этот же идентификатор потока (типа pthread_t) может быть позже быть получен в самом потоке вызовом:

pthread_t pthread_self( void );


Предыдущий раздел: Оглавление Следующий раздел:
Параллельные потоки   Параметры создания потока

Поделиться: