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

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

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

 sleep(3);

 strcpy(message, "Bye!");

 pthread_exit("Thank you for the CPU time");

}

Π˜Ρ‚Π°ΠΊ:

1. ΠŸΠ΅Ρ€Π΅Π΄ компиляциСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ макрос _REENTRANT. Π’ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… систСмах Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ _POSIX_C_SOURCE, Π½ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π² этом Π½Π΅Ρ‚ нСобходимости.

2. Π”Π°Π»Π΅Π΅ Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° скомпонована с подходящСй Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’ случаС маловСроятной ситуации примСнСния старой вСрсии дистрибутива Linux, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ NPTL Π½Π΅ являСтся Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρƒ вас Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ΠΆΠ΅Π»Π°Π½ΠΈΠ΅ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π΅Π΅, хотя большая Ρ‡Π°ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π² этой Π³Π»Π°Π²Π΅, совмСстима со старой Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π² Linux. Π›Π΅Π³ΠΊΠΈΠΉ способ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ β€” Π·Π°Π³Π»ΡΠ½ΡƒΡ‚ΡŒ Π² Ρ„Π°ΠΉΠ» /usr/include/pthread.h. Если Π² этом Ρ„Π°ΠΉΠ»Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² качСствС Π΄Π°Ρ‚Ρ‹ авторского ΠΏΡ€Π°Π²Π° (copyright date) 2003 Π³. ΠΈΠ»ΠΈ Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ·Π΄Π½ΠΈΠΉ, ΠΏΠΎΡ‡Ρ‚ΠΈ навСрняка Ρƒ вас рСализация NPTL. Если ΡƒΠΊΠ°Π·Π°Π½Π° Π±ΠΎΠ»Π΅Π΅ ранняя Π΄Π°Ρ‚Π°, ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ, самоС врСмя ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ дистрибутива Linux.

3. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΠΈΠ² ΠΈ установив Π½ΡƒΠΆΠ½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ ΡΠΊΠΎΠΌΠΏΠΎΠ½ΠΎΠ²Π°Ρ‚ΡŒ Π²Π°ΡˆΡƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

$ cc -D_REENTRANT -I/usr/include/nptl threadl.с -о thread1 -L/usr/lib/nptl -lpthread

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Если Π² вашСй систСмС ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ установлСна NPTL (Ρ‡Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ вСроятно), ΠΏΠΎΡ‡Ρ‚ΠΈ навСрняка Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½Ρ‹ ΠΎΠΏΡ†ΠΈΠΈ -I ΠΈ -L, ΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ простой Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

$ cc -D_REENTRANT thread1.с -о thread1 -lpthread

Π’ Π΄Π°Π½Π½ΠΎΠΉ Π³Π»Π°Π²Π΅ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ этот Π±ΠΎΠ»Π΅Π΅ простой Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ строки компиляции.

4. ΠšΠΎΠ³Π΄Π° Π²Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‚ΠΎ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ строки:

$ ./thread1

Waiting for thread to finish...

thread_function is running. Argument was Hello World

Thread joined, it returned Thank you for the CPU time

Message is now Bye!

Π‘Ρ‚ΠΎΠΈΡ‚ ΠΏΠΎΡ‚Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Π½Π° Π°Π½Π°Π»ΠΈΠ· Π΄Π°Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π΅ ΠΊΠ°ΠΊ основу Π² Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² этой Π³Π»Π°Π²Ρ‹.

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

Π’Ρ‹ ΠΎΠ±ΡŠΡΠ²Π»ΡΠ΅Ρ‚Π΅ ΠΏΡ€ΠΎΡ‚ΠΎΡ‚ΠΈΠΏ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π΅Π³ΠΎ создадитС:

void *thread_function(void *arg);

Как Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ функция pthread_create, данная функция ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС своСго СдинствСнного ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° void ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° void. (ΠœΡ‹ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ thread_function Ρ‡Π΅Ρ€Π΅Π· ΠΌΠΈΠ½ΡƒΡ‚Ρƒ.)

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main объявлСно нСсколько ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈ Π·Π°Ρ‚Π΅ΠΌ осущСствляСтся Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_create, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°Ρ‡Π°Ρ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

pthread_t a_thread;

void *thread_result;

res = pthread_create(&a_thread, NULL, thread_function, (void *)message);

Π’Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚Π΅ адрСс ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ‚ΠΈΠΏΠ° pthread_t, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒ Π² дальнСйшСм для ссылки Π½Π° ΠΏΠΎΡ‚ΠΎΠΊ. Π’Ρ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΌΠ΅Π½ΡΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π·Π°Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, поэтому Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚Π΅ NULL. ПослСдниС Π΄Π²Π° ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° β€” вызываСмая функция ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΉ Π΅ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€.

Если Π²Ρ‹Π·ΠΎΠ² Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ, Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ (main) продолТаСтся ΠΈ выполняСт ΠΊΠΎΠ΄, располоТСнный слСдом Π·Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pthread_create, Π° Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠ±Ρ€Π°Π·Π½ΠΎ Π½Π°Π·Π²Π°Π½Π½ΠΎΠΉ thread_function.

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ провСряСт, запустился Π»ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_join:

res = pthread_join(a_thread, &thread_result);

Π—Π΄Π΅ΡΡŒ Π²Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΆΠ΄Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΈΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ, ΠΈ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π­Ρ‚Π° функция, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Π±ΡƒΠ΄Π΅Ρ‚ ΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ. Π—Π°Ρ‚Π΅ΠΌ ΠΎΠ½Π° Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ содСрТимоС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΈ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ.

Новый ΠΏΠΎΡ‚ΠΎΠΊ Π½Π°Ρ‡ΠΈΠ½Π°Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅, запуская Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ thread_function, которая Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ свои Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, засыпаСт Π½Π° ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ ΠΏΠ΅Ρ€ΠΈΠΎΠ΄, обновляСт Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, возвращая строку Π² ΠΏΠΎΡ‚ΠΎΠΊ main. Новый ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΈΡˆΠ΅Ρ‚ Π² Ρ‚ΠΎΡ‚ ΠΆΠ΅ массив message, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ Ρƒ исходного ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΅ΡΡ‚ΡŒ доступ. Если Π±Ρ‹ Π²Ρ‹ Π²Ρ‹Π·Π²Π°Π»ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ fork вмСсто pthread_create, массив прСдставлял Π±Ρ‹ собой копию массива message, Π° Π½Π΅ сам массив.

ΠžΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅

Π’ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠΈ 12.2 ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ, ΠΊΠ°ΠΊ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, которая провСряСт ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². (Π’Ρ‹, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, примСняСтС ΠΎΠ΄Π½ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½ΡƒΡŽ систСму, ЦП Π±ΡƒΠ΄Π΅Ρ‚ искусно ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Ρ‚ΡŒΡΡ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, Π° Π½Π΅ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΎΠ±Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ ядра процСссора Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹ΠΌΠΈ срСдствами.) ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²Ρ‹ Π½Π΅ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°Π»ΠΈΡΡŒ Π΅Ρ‰Π΅ с ΠΊΠ°ΠΊΠΈΠΌΠΈ-Π»ΠΈΠ±ΠΎ функциями синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², это Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‡Π΅Π½ΡŒ нСэффСктивная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, Π΄Π΅Π»Π°ΡŽΡ‰Π°Ρ Π½Π΅Ρ‡Ρ‚ΠΎ, ΠΈΠΌΠ΅Π½ΡƒΠ΅ΠΌΠΎΠ΅ опросом (polling) Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². И снова Π²Ρ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ΡΡŒ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ всС, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ двумя ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ Π² процСссС.

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 12.2. ΠžΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° thread2.c Π² этом ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠΈ создаСтся Π·Π° счСт Π½Π΅Π±ΠΎΠ»ΡŒΡˆΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ thread1.c. Π’Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ для опрСдСлСния Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰Π΅Π³ΠΎΡΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Π€Π°ΠΉΠ»Ρ‹ с ΠΏΠΎΠ»Π½Ρ‹ΠΌΠΈ тСкстами ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ с Web-сайта ΠΊΠ½ΠΈΠ³ΠΈ.

int run_now = 1;

Π—Π°Π΄Π°ΠΉΡ‚Π΅ run_now Ρ€Π°Π²Π½ΠΎΠΉ 1, ΠΊΠΎΠ³Π΄Π° выполняСтся функция main, ΠΈ 2, ΠΊΠΎΠ³Π΄Π° выполняСтся Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ.

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ main послС создания Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄ΠΎΠ±Π°Π²ΡŒΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

int print_count1 = 0;

while (print_count1+ < 20) {

 if (run_now == 1) {

  printf("1");

  run_now = 2;

 } else {

  sleep(1);

 }

}

Если пСрСмСнная run_now Ρ€Π°Π²Π½Π° 1, Π²Ρ‹Π²Π΅Π΄ΠΈΡ‚Π΅ "1" ΠΈ присвойтС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 2. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π²Ρ‹ Π½Π° ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ врСмя засыпаСтС ΠΈ снова провСряСтС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π’Ρ‹ ΠΆΠ΄Π΅Ρ‚Π΅, ΠΏΠΎΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ измСнится Π½Π° 1, провСряя врСмя ΠΎΡ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ снова. Π­Ρ‚ΠΎΡ‚ ΠΏΡ€ΠΈΠ΅ΠΌ называСтся Ρ†ΠΈΠΊΠ»Π°ΠΌ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΈΠ»ΠΈ Π΄Π΅ΡΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ оТидания (busy wait), нСсмотря, Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° засыпаСт Π½Π° сСкунду ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°ΠΌΠΈ. ПозТС Π² этой Π³Π»Π°Π²Π΅ Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅, ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это Π»ΡƒΡ‡ΡˆΠ΅.

Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ thread_function, Π³Π΄Π΅ выполняСтся ваш Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹ Π΄Π΅Π»Π°Π΅Ρ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π½ΠΎ Ρ‚ΠΎ ΠΆΠ΅ самоС, Π½ΠΎ с ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Ρ‹ΠΌΠΈ значСниями.

int print_count2 = 0;

while (print_count2++ < 20) {

 if (run_now == 2) {

  printf("2");

  run_now = 1;

 } else {

  sleep(1);

 }

}

Π’Ρ‹ удаляСтС ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‚.ΠΊ. ΠΎΠ½ΠΈ вас большС Π½Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΡƒΡŽΡ‚.

Когда Π²Ρ‹ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‚ΠΎ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π²ΠΎΠ΄. (Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ для формирования Π²Ρ‹Π²ΠΎΠ΄Π°, особСнно Π½Π° машинС с одноядСрным ЦП, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ потрСбуСтся нСсколько сСкунд.)

$ cc -D_REENTRANT thread2.с -о thread2 -lpthread

$ ./thread2

12121212121212121212

Waiting for thread to finish...

Thread joined

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

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ заставляСт Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ, задавая ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ run_now ΠΈ Π·Π°Ρ‚Π΅ΠΌ оТидая, ΠΏΠΎΠΊΠ° Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ΡŒ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. Из ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΎΡ‚ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΊ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ автоматичСскими ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΎΠ½Π° дСмонстрируСт Ρ‚ΠΎΡ‡ΠΊΡƒ, совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡƒΡŽ ΠΎΠ±ΠΎΠΈΠΌΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, β€” ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ run_now.

Бинхронизация

Π’ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ Π²Ρ‹ Π²ΠΈΠ΄Π΅Π»ΠΈ, Ρ‡Ρ‚ΠΎ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, Π½ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ Π½ΠΈΠΌΠΈ Ρ‚ΠΎΠΏΠΎΡ€Π½Ρ‹ΠΉ ΠΈ ΠΎΡ‡Π΅Π½ΡŒ нСэффСктивный. К ΡΡ‡Π°ΡΡ‚ΡŒΡŽ, сущСствуСт ряд Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹Ρ… для прСдоставлСния Π»ΡƒΡ‡ΡˆΠΈΡ… способов управлСния исполнСниСм ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ доступа ΠΊ Π²Π°ΠΆΠ½Ρ‹ΠΌ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°ΠΌ ΠΊΠΎΠ΄Π°.

Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ рассмотрим Π΄Π²Π° основных ΠΌΠ΅Ρ‚ΠΎΠ΄Π°: сСмафоры, Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠ°ΠΊ стороТа, ΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‰ΠΈΠ΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Ρ‹ ΠΊΠΎΠ΄Π°, ΠΈ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΡ‹ ΠΈΠ»ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠ΅ сСмафоры, Π΄Π΅ΠΉΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠ΅ ΠΊΠ°ΠΊ устройство Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ (ΠΎΡ‚ΡΡŽΠ΄Π° ΠΈ имя β€” ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠΉ сСмафор) для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°. На самом Π΄Π΅Π»Π΅ эти ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΏΠΎΡ…ΠΎΠΆΠΈ, ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ описан Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Ρ… Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ ситуации, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… сСмантика ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΎΠ΄ΠΈΠ½ Π±ΠΎΠ»Π΅Π΅ Π²Ρ‹Ρ€Π°Π·ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, Ρ‡Π΅ΠΌ Π΄Ρ€ΡƒΠ³ΠΎΠΉ. НапримСр, ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ доступом ΠΊ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ области совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ памяти, ΠΊ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡ‚ΠΎΠΊ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ, Π±ΠΎΠ»Π΅Π΅ СстСствСнным каТСтся ΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠΉ сСмафор ΠΈΠ»ΠΈ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ. Для управлСния доступом ΠΊ ряду ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Π² Ρ†Π΅Π»ΠΎΠΌ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, прСдоставлСниС ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΎΠ΄Π½ΠΎΠΉ Ρ‚Π΅Π»Π΅Ρ„ΠΎΠ½Π½ΠΎΠΉ Π»ΠΈΠ½ΠΈΠΈ ΠΈΠ· Π½Π°Π±ΠΎΡ€Π°, Π²ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΏΡΡ‚ΡŒ доступных Π»ΠΈΠ½ΠΈΠΉ, большС ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ сСмафор. Какой ΠΌΠ΅Ρ‚ΠΎΠ΄ Π²Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ Π²Ρ‹, зависит ΠΎΡ‚ Π»ΠΈΡ‡Π½Ρ‹Ρ… ΠΏΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚Π΅Π½ΠΈΠΉ ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ подходящСго для вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°.

Бинхронизация с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ сСмафоров

Для сСмафоров Π΅ΡΡ‚ΡŒ Π΄Π²Π° Π½Π°Π±ΠΎΡ€Π° интСрфСйсных Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ: ΠΎΠ΄ΠΈΠ½ взят ΠΈΠ· POSIX Realtime Extensions (дополнСния POSIX для Ρ€Π΅ΠΆΠΈΠΌΠ° Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ) ΠΈ примСняСтся для ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ, извСстный ΠΊΠ°ΠΊ сСмафоры System V, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ примСняСтся для синхронизации процСссов. (ΠœΡ‹ обсудим Π²Ρ‚ΠΎΡ€ΠΎΠΉ Ρ‚ΠΈΠΏ Π² Π³Π»Π°Π²Π΅ 14.) Оба Π½Π°Π±ΠΎΡ€Π° Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ взаимозамСняСмости ΠΈ хотя ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΡ…ΠΎΠΆΠΈ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ€Π°Π·Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.