Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π² LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 141

Автор НСйл ΠœΡΡ‚ΡŒΡŽ

 }

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

 res = pthread_join(a_thread, &thread_result);

 if (res != 0) {

  perror("Thread join failed");

  exit(EXIT_FAILURE);

 }

 exit(EXIT_SUCCESS);

}


void *thread_function(void *arg) {

 int i, res;

 res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

 if (res != 0) {

  perror("Thread pthread_setcancelstate failed");

  exit(EXIT_FAILURE);

 }

 res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

 if (res != 0) {

  perror{"Thread pthread_setcanceltype failed");

  exit(EXIT_FAILURE);

 }

 printf("thread_function is running\n");

 for(i = 0; i < 10; i++) {

  printf("Thread is still running (%d)...\n", i);

  sleep(1);

 }

 pthread_exit(0);

}

Когда Π²Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‚ΠΎ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π²ΠΎΠ΄, Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°:

$ ./thread7

thread_function is running

Thread is still running (0)...

Thread is still running (1)...

Thread is still running (2)...

Canceling thread...

Waiting for thread to finish...

$

Как это Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚

ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π±Ρ‹Π» создан ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ способом, основной ΠΏΠΎΡ‚ΠΎΠΊ засыпаСт (Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π°Ρ‚ΡŒ Π½ΠΎΠ²ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ врСмя для запуска) ΠΈ Π·Π°Ρ‚Π΅ΠΌ отправляСт запрос Π½Π° ΠΎΡ‚ΠΌΠ΅Π½Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

sleep(3);

printf("Cancelling thread...\n");

res = pthread_cancel(a_thread);

if (res != 0) {

 perror("Thread cancelation failed");

 exit(EXIT_FAILURE);

}

Π’ созданном ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Π²Ρ‹ сначала Π·Π°Π΄Π°Π΅Ρ‚Π΅ состояниС ΠΎΡ‚ΠΌΠ΅Π½Ρ‹, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠΈΡ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°:

res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

if (res != 0) {

 perror("Thread pthread_setcancelstate failed");

 exit(EXIT_FAILURE);

}

Π”Π°Π»Π΅Π΅ Π²Ρ‹ Π·Π°Π΄Π°Π΅Ρ‚Π΅ Ρ‚ΠΈΠΏ ΠΎΡ‚ΠΌΠ΅Π½Ρ‹ PTHREAD_CANCEL_DEFERRED:

res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

if (res != 0) {

 perror("Thread pthread_setcanceltype failed");

 exit(EXIT_FAILURE);

}

И Π² ΠΊΠΎΠ½Ρ†Π΅ ΠΏΠΎΡ‚ΠΎΠΊ ΠΆΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΌΠ΅Π½Ρƒ:

for (i = 0; i < 10; i++) {

 printf("Thread is still running (%d)...\n", i);

 sleep(1);

}

ΠŸΠΎΡ‚ΠΎΠΊΠΈ Π² ΠΈΠ·ΠΎΠ±ΠΈΠ»ΠΈΠΈ

Π”ΠΎ настоящСго ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Ρƒ нас всСгда Π±Ρ‹Π» ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ исполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΡΠΎΠ·Π΄Π°ΡŽΡ‰ΠΈΠΉ Π΅Ρ‰Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΌΡ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ Π΄ΡƒΠΌΠ°Π»ΠΈ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ (ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 12.8).

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 12.8. Много ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Π’ Π·Π°ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ этой Π³Π»Π°Π²Ρ‹ thread8.c ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² ΠΎΠ΄Π½ΠΎΠΉ ΠΈ Ρ‚ΠΎΠΉ ΠΆΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΈΡ… снова Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, ΠΎΡ‚Π»ΠΈΡ‡Π°ΡŽΡ‰Π΅ΠΉΡΡ ΠΎΡ‚ порядка ΠΈΡ… создания.

#include <stdio.h>

#include <unistd.h>

#include <stdlib.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_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--) {

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

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

  lots of threads--) {

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