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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ для Linux. ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 18

Автор ΠœΠ°Ρ€ΠΊ ΠœΠΈΡ‚Ρ‡Π΅Π»Π»

Π’ листингС 4.3 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π° исправлСнная вСрсия Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ main() ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ, Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС функция main() Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ, ΠΏΠΎΠΊΠ° ΠΎΠ±Π° Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½Π΅ выполнят свои задания ΠΈ Π½Π΅ пСрСстанут ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ ΠΈΠΌ структуры.

Листинг 4.3. Π˜ΡΠΏΡ€Π°Π²Π»Π΅Π½Π½Π°Ρ функция main() ΠΈΠ· Ρ„Π°ΠΉΠ»Π° thread-create.c

int main() {

 pthread_t thread1_id;

 pthread_t thread2_id;

 struct char_print_parms thread1_args;

 struct char_print_parms thread2_args;


 /* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰Π΅Π³ΠΎ 30000

    символов 'x'. */

 thread1_args.character = 'x';

 thread1_args.count = 30000;

 pthread_create(&thread1_id, NULL, &char_print, &thread1_args);


 /* Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°ΡŽΡ‰Π΅Π³ΠΎ

    20000 символов 'o'. */

 thread2_args.character = 'o';

 thread2_args.count = 20000;

 pthread_create(&thread2_id, NULL, &char_print, &thread2_args);


 /* УбСТдаСмся, Ρ‡Ρ‚ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. */

 pthread_join(thread1_id, NULL);


 /* УбСТдаСмся, Ρ‡Ρ‚ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΡΡ Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ. */

 pthread_join(thread2_id, NULL);


 /* Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ спокойно Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ. */

 return 0;

}

ΠœΠΎΡ€Π°Π»ΡŒ сСй басни Ρ‚Π°ΠΊΠΎΠ²Π°: ΡƒΠ±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅, ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΡƒ ΠΏΠΎ ссылкС, Π½Π΅ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ (Π΄Π°ΠΆΠ΅ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ) Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ свою Ρ€Π°Π±ΠΎΡ‚Ρƒ с Π½ΠΈΠΌΠΈ. Π­Ρ‚ΠΎ относится ΠΊΠ°ΠΊ ΠΊ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ, удаляСмым автоматичСски ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Ρ‹ своСй области видимости, Ρ‚Π°ΠΊ ΠΈ ΠΊ динамичСским ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ, удаляСмым с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ free() (ΠΈΠ»ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Π° delete Π² C++).

4.1.3. ЗначСния, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ

Если Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_join() Π½Π΅ Ρ€Π°Π²Π΅Π½ NULL, Ρ‚ΠΎ Π² Π½Π΅Π³ΠΎ помСщаСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ. Как ΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚ΠΈΠΏ void*. Если ΠΏΠΎΡ‚ΠΎΠΊ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ΅ число Ρ‚ΠΈΠΏΠ° int, Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ свободно привСсти ΠΊ Ρ‚ΠΈΠΏΡƒ void*, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_join().[13]

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, прСдставлСнная Π² листингС 4.4, Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ вычисляСт n-Π΅ простоС число ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π΅Π³ΠΎ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Π’Π΅ΠΌ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ функция main() ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ свои собствСнныС вычислСния. Π‘Ρ€Π°Π·Ρƒ признаСмся: Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ дСлСния, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ compute_prime(), вСсьма нСэффСктивСн. Π’ ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ числСнным ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌ описаны Π±ΠΎΠ»Π΅Π΅ ΠΌΠΎΡ‰Π½Ρ‹Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, "Ρ€Π΅ΡˆΠ΅Ρ‚ΠΎ ЭратосфСна").

Листинг 4.4. (primes.с) ВычислСниС простых чисСл Π² ΠΏΠΎΡ‚ΠΎΠΊΠ΅

#include <pthread.h>

#include <stdio.h>


/* Находим простоС число с порядковым Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ N, Π³Π΄Π΅ N -- это

   Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ ARG. */

void* compute_prime(void* arg) {

 int candidate = 2;

 int n = *((int*)arg);


 while (1) {

  int factor;

  int is_prime = 1;


  /* ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° простого числа ΠΏΡƒΡ‚Π΅ΠΌ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ дСлСния. */

  for (factor = 2; factor < candidate; ++factor)

   if (candidate % factor == 0) {

    is_prime = 0;

    break;

   }

  /* Π­Ρ‚ΠΎ Ρ‚ΠΎ простоС число, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ? */

  if (is_prime) {

   if (--n == 0)

    /* Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π½Π°ΠΉΠ΄Π΅Π½Π½ΠΎΠ΅ число Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. */

    return (void*)candidate;

  }

  ++candidate;

 }

 return NULL;

}


int main() {

 pthread_t thread;

 int which_prime = 5000;

 int prime;


 /* ЗапускаСм ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‰ΠΈΠΉ 5000-Π΅ простоС число. */

 pthread_create(&thread, NULL, &compute_prime, &which_prime);

 /* ВыполняСм Π΄Ρ€ΡƒΠ³ΠΈΠ΅ дСйствия. */

 /* ДоТидаСмся Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅ΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ ΠΈΠΌ

    Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. */

 pthread_join(thread, (void*)&prime);

 /* ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ вычислСнный Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. */

 printf("The %dth prime number is %d.\n", which_prime, prime);

 return 0;

}

4.1.4. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎΠ± ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

Иногда Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ выполняСт Π΅Π΅ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚. Ѐункция pthread_self() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΎΠ½Π° Π²Ρ‹Π·Π²Π°Π½Π°. Для сравнСния Π΄Π²ΡƒΡ… Ρ€Π°Π·Π½Ρ‹Ρ… ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΠΎΠ² ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° функция pthread_equal().

Π­Ρ‚ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΡƒΠ΄ΠΎΠ±Π½Ρ‹ для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ соотвСтствия Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ. НапримСр, ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_join(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΆΠ΄Π°Ρ‚ΡŒ самого сСбя (Π² ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠΉ ситуации возвращаСтся ΠΊΠΎΠ΄ ошибки EDEADLK). Π˜Π·Π±Π΅ΠΆΠ°Ρ‚ΡŒ этой ошибки позволяСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ°:

if (!pthread_equal(pthread_self(), other_thread)) pthread_join(other_thread, NULL);

4.1.5. Атрибуты ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²

ΠŸΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ β€” это ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ настройки повСдСния ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². ВспомнитС, Ρ‡Ρ‚ΠΎ функция pthread_create() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚, ΡΠ²Π»ΡΡŽΡ‰ΠΈΠΉΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΏΠΎΡ‚ΠΎΠΊΠ°. Если этот ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Ρ€Π°Π²Π΅Π½ NULL, ΠΏΠΎΡ‚ΠΎΠΊ конфигурируСтся Π½Π° основании стандартных Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ².

Для задания собствСнных Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΏΠΎΡ‚ΠΎΠΊΠ° Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ дСйствия.

1. Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚ΠΈΠΏΠ° pthread_attr_t.

2. Π’Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_attr_init(), ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π΅ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π­Ρ‚Π° функция присваиваСт Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌ стандартныС значСния.

3. Π—Π°ΠΏΠΈΡˆΠΈΡ‚Π΅ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Π΅ значСния Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ².

4. ΠŸΠ΅Ρ€Π΅Π΄Π°ΠΉΡ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_create().

5. Π’Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_attr_destroy(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈΠ· памяти. Π‘Π°ΠΌΠ° пСрСмСнная pthread_attr_t Π½Π΅ удаляСтся; Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_attr_init().

Один ΠΈ Ρ‚ΠΎΡ‚ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использован для запуска Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². НСт нСобходимости Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΠΏΠΎΡ‚ΠΎΠΊ Π±Ρ‹Π» создан.

Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° Linux-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ интСрСс прСдставляСт ΠΎΠ΄ΠΈΠ½-СдинствСнный Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ (ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² прилоТСниях Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ): статус отсоСдинСния ΠΏΠΎΡ‚ΠΎΠΊΠ°. ΠŸΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ создан ΠΊΠ°ΠΊ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ) ΠΈΠ»ΠΈ отсоСдинСнный. ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ процСссу, послС своСго Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π½Π΅ удаляСтся автоматичСски ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмой Linux. Код Π΅Π³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ хранится Π³Π΄Π΅-Ρ‚ΠΎ Π² систСмС (ΠΊΠ°ΠΊ Ρƒ процСсса-Π·ΠΎΠΌΠ±ΠΈ), ΠΏΠΎΠΊΠ° ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡƒΠ΄ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_join(), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Волько Ρ‚ΠΎΠ³Π΄Π° рСсурсы ΠΏΠΎΡ‚ΠΎΠΊΠ° ΡΡ‡ΠΈΡ‚Π°ΡŽΡ‚ΡΡ освобоТдСнными. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, отсоСдинСнный ΠΏΠΎΡ‚ΠΎΠΊ, Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ²ΡˆΠΈΡΡŒ, сразу уничтоТаСтся. Π”Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ Π½Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΏΠΎ ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡŽ ΠΊ Π½Π΅ΠΌΡƒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_join() ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ ΠΈΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅.

Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°Π΄Π°Ρ‚ΡŒ статус отсоСдинСния ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ pthread_attr_setdetachstate(). ΠŸΠ΅Ρ€Π²Ρ‹ΠΉ Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΏΠΎΡ‚ΠΎΠΊΠ°, Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹ΠΉ статус. ΠžΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ, поэтому Π² качСствС Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° ΠΈΠΌΠ΅Π΅Ρ‚ смысл ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ PTHREAD_CREATE_DETACHED.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, прСдставлСнная Π² листингС 4.5, создаСт отсоСдинСнный ΠΏΠΎΡ‚ΠΎΠΊ, устанавливая ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΏΠΎΡ‚ΠΎΠΊΠ°.

Листинг 4.5. (detached.c) Π¨Π°Π±Π»ΠΎΠ½ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, ΡΠΎΠ·Π΄Π°ΡŽΡ‰Π΅ΠΉ отсоСдинСнный ΠΏΠΎΡ‚ΠΎΠΊ

#include <pthread.h>


void* thread_function(void* thread_arg) {

 /* Π’Π΅Π»ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ... */

}


int main() {

 pthread_attr_t attr;

 pthread_t thread;

 pthread_attr_init(&attr);

 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

 pthread_create(&thread, &attr, &thread_function, NULL);

 pthread_attr_destroy(&attr);


 /* Π’Π΅Π»ΠΎ основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹... */


 /* Π”ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒΡΡ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π²Ρ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° Π½Π΅Ρ‚ нСобходимости. */

 return 0;

}

Π”Π°ΠΆΠ΅ Ссли ΠΏΠΎΡ‚ΠΎΠΊ Π±Ρ‹Π» создан ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΡ‹ΠΌ, Π΅Π³ΠΎ ΠΏΠΎΠ·Π΄Π½Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ отсоСдинСнным. Для этого Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_detach(). ΠžΠ±Ρ€Π°Ρ‚Π½ΠΎΠ΅ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

4.2. ΠžΡ‚ΠΌΠ΅Π½Π° ΠΏΠΎΡ‚ΠΎΠΊΠ°

ΠžΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΠΏΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ вслСдствиС Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pthread_exit(). Но сущСствуСт Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Π·Π°ΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ° ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ. Π­Ρ‚ΠΎ называСтся ΠΎΡ‚ΠΌΠ΅Π½ΠΎΠΉ, ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠ½ΡƒΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΏΠΎΡ‚ΠΎΠΊΠ°.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊ, Π²Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ pthread_cancel(), ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π΅ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π”Π°Π»Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π’ΠΎΠΎΠ±Ρ‰Π΅-Ρ‚ΠΎ, это ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ с Ρ†Π΅Π»ΡŒΡŽ освобоТдСния рСсурсов, Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ являСтся отсоСдинСнным. ΠžΡ‚ΠΌΠ΅Π½Π΅Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ PTHREAD_CANCELED.

Π’ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ… случаях ΠΏΠΎΡ‚ΠΎΠΊ выполняСт ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСльзя просто Π²Π·ΡΡ‚ΡŒ ΠΈ ΠΏΡ€Π΅Ρ€Π²Π°Ρ‚ΡŒ. НапримСр, ΠΏΠΎΡ‚ΠΎΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ рСсурсы, ΠΏΠΎΡ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с Π½ΠΈΠΌΠΈ, Π° Π·Π°Ρ‚Π΅ΠΌ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ. Если ΠΎΡ‚ΠΌΠ΅Π½Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ Π³Π΄Π΅-Ρ‚ΠΎ посСрСдинС, ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ занятыС рСсурсы станСт Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, вслСдствиС Ρ‡Π΅Π³ΠΎ ΠΎΠ½ΠΈ окаТутся потСрянными для систСмы. Π§Ρ‚ΠΎΠ±Ρ‹ ΡƒΡ‡Π΅ΡΡ‚ΡŒ эту ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ, ΠΏΠΎΡ‚ΠΎΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Π³Π΄Π΅ ΠΈ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ΠΌΠ΅Π½Π΅Π½.