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

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

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

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>