Чтение онлайн

на главную - закладки

Жанры

Основы программирования в Linux
Шрифт:

Как это работает

На сей раз вы создаете массив идентификаторов потоков:

pthread_t a_thread[NUM_THREADS];

и заключаете в цикл создание нескольких потоков:

for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {

 res = pthread_create(&(a_thread[lots_of_threads]), NULL,

thread_function, (void *)&lots_of_threads);

 if (res != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

 }

 sleep(1);

}

Затем

потоки сами по себе ждут в течение случайного промежутка времени, прежде чем начать выполнение:

void *thread_function(void *arg) {

 int my_number = *(int *)arg;

 int rand_num;

 printf("thread_function is running. Argument was %d\n", my_number);

 rand_num = 1+(int)(9.0* rand/(RAND_MAX+1.0));

 sleep(randnum);

 printf("Bye from %d\n", my_number);

 pthread_exit(NULL);

}

В это время в основном (исходном) потоке вы ждете, чтобы собрать потоки, но не в том порядке, в каком вы их создали:

for (lots_of_threads = NUM_THREADS - 1; lots_of_threads >= 0; lots_of_threads--) {

 res = pthread_join(a_thread[lots_of__threads], &thread_result);

 if (res == 0) {

printf("Picked up a thread\n");

 } else {

perror("pthread_join failed");

 }

}

Если вы попробуете выполнить программу без вызова

sleep
, то увидите странный эффект: некоторые потоки запускаются с одним и тем же номером, например, вы можете получить вывод, похожий на следующий:

thread_function is running. Argument was 0

thread_function is running. Argument was 2

thread_function is running. Argument was 2

thread_function is running. Argument was 4

thread_function is running. Argument was 4

thread_function is running. Argument was 5

Waiting for threads to finish...

Bye from 5

Picked up a thread

Bye from 2

Bye from 0

Bye from 2

Bye from 4

Bye from 4

Picked up a thread

Picked up a thread

Picked up a thread

Picked up a thread

Picked up a thread

All done

Вы

догадались, что произошло? Потоки запускаются, используя локальную переменную как аргумент функции потока. Эта переменная обновляется в цикле. Далее приведены ошибочные строки:

for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {

 res = pthread_create(&(a_thread[lots_of_threads]), NULL,

thread_function, (void *)&lots_of_threads);

Если поток

main
выполняется достаточно быстро, он может искажать аргумент (
lots_of_threads
) для некоторых потоков. Поведение, подобное этому, наблюдается, когда недостаточно внимания уделяется совместно используемым переменным и множественным путям исполнения (multiple execution paths). Мы предупреждали вас о том, что программирование потоков требует повышенного внимания при разработке! Для исправления ошибки вам следует передавать непосредственно значение следующим образом:

res = pthread_create(&(a_thread[lots_of_threads]), NULL,

 thread_function, (void *)lots_of_threads);

и конечно изменить

thread_function
:

void *thread_function(void *arg) {

 int my_number = (int)arg;

Все исправления, выделенные цветом, показаны в программе thread8a.c.

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <pthread.h>

#define NUM_THREADS 6

void *thread_function(void *arg);

int main {

 int res;

 pthread_t a_thread[NUM_THREADS];

 void *thread_result;

 int lots_of_threads;

 for (lots_of_threads = 0; lots_of_threads < NUM_THREADS; lots_of_threads++) {

res = pthread_create(&(a_thread[lots_of_thread]), NULL,

thread_function, (void*)lots_оf_threads);

if (res != 0) {

perror("Thread creation failed");

exit(EXIT_FAILURE);

}

 }

 printf("Waiting for threads to finish...\n");

Поделиться:
Популярные книги

Похвали меня

Кейт Сара
Любовные романы:
зарубежные любовные романы
5.00
рейтинг книги
Похвали меня

Звезды на приеме у психолога. Психоанализ знаменитых личностей

Гарифуллин Рамиль Рамзиевич
Научно-образовательная:
психология
5.00
рейтинг книги
Звезды на приеме у психолога. Психоанализ знаменитых личностей

"Княгиня Ольга". Компиляция. Книги 1-19

Дворецкая Елизавета Алексеевна
Княгиня Ольга
Приключения:
исторические приключения
5.00
рейтинг книги
Княгиня Ольга. Компиляция. Книги 1-19

Вавилон - 17 [Вавилон - 17. Нова. Падение башен]

Дилэни Сэмюэль
Фантастика:
научная фантастика
5.00
рейтинг книги
Вавилон - 17 [Вавилон - 17. Нова. Падение башен]

Ошибки богов. Тетралогия

Танков Вячеслав
Ошибки богов
Фантастика:
фэнтези
5.00
рейтинг книги
Ошибки богов. Тетралогия

Золото Вильгельма

Искандер Фазиль Абдулович
Козы и Шекспир
Проза:
современная проза
5.00
рейтинг книги
Золото Вильгельма

Нас ждет Севастополь

Соколов Георгий Владимирович
Проза:
военная проза
советская классическая проза
5.00
рейтинг книги
Нас ждет Севастополь

10 вождей. От Ленина до Путина

Млечин Леонид Михайлович
Документальная литература:
биографии и мемуары
5.20
рейтинг книги
10 вождей. От Ленина до Путина

Шерас

Стародубцев Дмитрий
Фантастика:
фэнтези
6.25
рейтинг книги
Шерас

Неизвестный фактор (Романы)

Нортон Андрэ
Фантастика:
фэнтези
5.00
рейтинг книги
Неизвестный фактор (Романы)

Вершитель

Осадчук Алексей Витальевич
7. Андердог
Фантастика:
фэнтези
рпг
5.00
рейтинг книги
Вершитель

Неучтенный элемент. Том 3

NikL
3. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 3

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Темная Башня 4 (Колдун и Кристалл)

Кинг Стивен
Фантастика:
боевая фантастика
фэнтези
научная фантастика
8.12
рейтинг книги
Темная Башня 4 (Колдун и Кристалл)