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

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

Жанры

Основы программирования в 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");

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

"Фантастика 2025-103". Компиляция. Книги 1-17

Поселягин Владимир Геннадьевич
Фантастика 2025. Компиляция
Фантастика:
боевая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Фантастика 2025-103. Компиляция. Книги 1-17

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Я снова князь. Книга XXIII

Дрейк Сириус
23. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я снова князь. Книга XXIII

Курсант: назад в СССР

Дамиров Рафаэль
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Курсант: назад в СССР

Ярар. Начало

Грехов Тимофей
1. Ярар
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ярар. Начало

Двойник Короля 6

Скабер Артемий
6. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 6

Гримуар темного лорда V

Грехов Тимофей
5. Гримуар темного лорда
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Гримуар темного лорда V

Кодекс Охотника. Книга V

Винокуров Юрий
5. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.50
рейтинг книги
Кодекс Охотника. Книга V

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Студент из прошлого тысячелетия

Еслер Андрей
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Студент из прошлого тысячелетия

Шатун. Лесной гамбит

Трофимов Ерофей
2. Шатун
Фантастика:
боевая фантастика
7.43
рейтинг книги
Шатун. Лесной гамбит

Мы - истребители

Поселягин Владимир Геннадьевич
2. Я - истребитель
Фантастика:
альтернативная история
8.55
рейтинг книги
Мы - истребители

Я – Стрела. Трилогия

Суббота Светлана
Я - Стрела
Любовные романы:
любовно-фантастические романы
эро литература
6.82
рейтинг книги
Я – Стрела. Трилогия

Законник Российской Империи. Том 2

Ткачев Андрей Юрьевич
2. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
6.40
рейтинг книги
Законник Российской Империи. Том 2