Unix - статьи



         

Потоки и процессы - часть 3


Функция pthread_exit() представляет собой потоковый аналог функции _exit(). Аргумент функции pthread_exit(), значение типа void *, становится возвращаемым значением функции потока. Как (и кому?) функция потока может вернуть значение, если она не вызывается из программы явным образом? Для того, чтобы получить значение, возвращенное функцией потока, нужно воспользоваться функцией pthread_join(3). У этой функции два параметра. Первый параметр pthread_join(), – это идентификатор потока, второй параметр имеет тип «указатель на нетипизированный указатель». В этом параметре функция pthread_join() возвращает значение, возвращенное функцией потока. Конечно, в многопоточном приложении есть и более простые способы организовать передачу данных между потоками. Основная задача функции pthread_join() заключается, однако, в синхронизации потоков. Вызов функции pthread_join() приостанавливает выполнение вызвавшего ее потока до тех пор, пока поток, чей идентификатор передан функции в качестве аргумента, не завершит свою работу. Если в момент вызова pthread_join() ожидаемый поток уже завершился, функция вернет управление немедленно. Функцию pthread_join() можно рассматривать как эквивалент waitpid(2) для потоков. Эта функция позволяет вызвавшему ее потоку дождаться завершения работы другого потока. Попытка выполнить более одного вызова pthread_join() (из разных потоков) для одного и того же потока приведет к ошибке.

Посмотрим, как все это работает на практике. Ниже приводится фрагмент листинга программы threads, (полный текст программы вы найдете в в файле threads.c).

#include <stdlib.h> #include <stdio.h> #include <errno.h> #include <pthread.h> void * thread_func(void *arg) { int i; int loc_id = * (int *) arg; for (i = 0; i < 4; i++) { printf("Thread %i is running\n", loc_id); sleep(1); } } int main(int argc, char * argv[]) { int id1, id2, result; pthread_t thread1, thread2; id1 = 1; result = pthread_create(&thread1, NULL, thread_func, &id1); if (result != 0) { perror("Creating the first thread"); return EXIT_FAILURE; } id2 = 2; result = pthread_create(&thread2, NULL, thread_func, &id2); if (result != 0) { perror("Creating the second thread"); return EXIT_FAILURE; } result = pthread_join(thread1, NULL); if (result != 0) { perror("Joining the first thread"); return EXIT_FAILURE; } result = pthread_join(thread2, NULL); if (result != 0) { perror("Joining the second thread"); return EXIT_FAILURE; } printf("Done\n"); return EXIT_SUCCESS; }




Содержание  Назад  Вперед