Библиотека сайта rus-linux.net
Цилюрик О.И. 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 );
Предыдущий раздел: | Оглавление | Следующий раздел: |
Параллельные потоки | Параметры создания потока |