Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
thread_function is running. Argument was 1thread_function is running. Argument was 2thread_function is running. Argument was 3thread_function is running. Argument was 4Bye from 1thread_function is running. Argument was 5Waiting for threads to finish...Bye from 5Picked up a threadBye from 0Bye from 2Bye from 3Bye from 4Picked up a threadPicked up a threadPicked up a threadPicked up a threadPicked up a threadAll doneКак видите, вы создали много потоков и разрешили им завершаться в произвольной последовательности. В этой программе есть маленькая ошибка, которая проявит себя, если вы удалите вызов sleep из цикла, запускающего потоки. Мы включили ее, чтобы показать, как вы должны быть внимательны при написании программ, применяющих потоки. Вы нашли ее? В следующем разд. "Как это работает" будет дано объяснение.
Как это работает
На сей раз вы создаете массив идентификаторов потоков:
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 %dn", my_number); rand_num = 1+(int)(9.0* rand()/(RAND_MAX+1.0)); sleep(randnum); printf("Bye from %dn", 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 threadn"); } else { perror("pthread_join failed"); }}Если вы попробуете выполнить программу без вызова
sleepthread_function is running. Argument was 0thread_function is running. Argument was 2thread_function is running. Argument was 2thread_function is running. Argument was 4thread_function is running. Argument was 4thread_function is running. Argument was 5Waiting for threads to finish...Bye from 5Picked up a threadBye from 2Bye from 0Bye from 2Bye from 4Bye from 4Picked up a threadPicked up a threadPicked up a threadPicked up a threadPicked up a threadAll 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);Если поток
mainlots_of_threadsres = pthread_create(&(a_thread[lots_of_threads]), NULL, thread_function, (void *)lots_of_threads);и конечно изменить
thread_functionvoid *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>
