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_threads]), NULL, thread_function, (void*)&lots_of_threads);

  if (res != 0) {

   perror("Thread creation failed");

   exit(EXIT_FAILURE);

  }

  sleep(1);

 }

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

 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");

  }

 }

 printf("All done\n");

 exit(EXIT_SUCCESS);

}

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(rand_num);

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

 pthread_exit(NULL);

}

Выполнив эту программу, вы получите следующий вывод:

$ ./thread8

thread_function is running. Argument was 0

thread_function is running. Argument was 1

thread_function is running. Argument was 2

thread_function is running. Argument was 3

thread_function is running. Argument was 4

Bye from 1

thread_function is running. Argument was 5

Waiting for threads to finish...

Bye from 5

Picked up a thread

Bye from 0

Bye from 2

Bye from 3

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

Как видите, вы создали много потоков и разрешили им завершаться в произвольной последовательности. В этой программе есть маленькая ошибка, которая проявит себя, если вы удалите вызов 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 %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--) {

Перейти на страницу:

Похожие книги