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

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

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

<b>#include &lt;Ρ€thread.h&gt;</b>

<b>int pthread_mutex_init(pthread_mutex_t* mutex,</b>

<b>Β const pthread_mutexattr_t *mutexattr);</b>

<b>int pthread_mutex_lock(pthread_mutex_t* mutex);</b>

<b>int pthread_mutex_unlock(pthread mutex_t* mutex);</b>

<b>int pthread_mutex_destroy(pthread_mutex_t *mutex);</b>

Как ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ, Π² случаС ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ возвращаСтся 0 ΠΈ ΠΊΠΎΠ΄ ошибки Π² случаС Π°Π²Π°Ρ€ΠΈΠΉΠ½ΠΎΠ³ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ, Π½ΠΎ пСрСмСнная

errno
Π½Π΅ задаСтся, Π²Π°ΠΌ придСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π°.

Как ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ сСмафоров, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠΎΠ² ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Π½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π² Π΄Π°Π½Π½ΠΎΠΌ случаС Ρ‚ΠΈΠΏΠ°

pthread_mutex_t
. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
pthread_mutex_init
позволяСт Π·Π°Π΄Π°Ρ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°, ΡƒΠΏΡ€Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ Π΅Π³ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ‚ΠΈΠΏ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° β€” "fast". Π£ Π½Π΅Π³ΠΎ Π΅ΡΡ‚ΡŒ нСбольшой нСдостаток: Ссли ваша ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° попытаСтся Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ
pthread_mutex_lock
для ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° блокируСтся. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠΎΡ‚ΠΎΠΊ, ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½, ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚, ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ‚ Π² Ρ‚ΡƒΠΏΠΈΠΊΠΎΠ²ΡƒΡŽ ΡΠΈΡ‚ΡƒΠ°Ρ†ΠΈΡŽ. Π•ΡΡ‚ΡŒ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π»ΠΈΠ±ΠΎ провСрял Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Ρ‚Π°ΠΊΠΎΠΉ ситуации ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π» ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π»ΠΈΠ±ΠΎ дСйствовал рСкурсивно ΠΈ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π» мноТСствСнныС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ‚Π΅ΠΌ ΠΆΠ΅ самым ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, Ссли Π±ΡƒΠ΄Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠ΅ ΠΆΠ΅ количСство Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ Π² дальнСйшСм.

Установка Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ° Π² этой ΠΊΠ½ΠΈΠ³Π΅ Π½Π΅ рассматриваСтся, поэтому ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ

NULL
Π² ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ Π½Π° Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹, ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. Π”ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎΠ± ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π² ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠΌ справочном руководствС ΠΊ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ
pthread_mutex_init
.

Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ ΡƒΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 12.4.Β 

Π£ΠΏΡ€Π°ΠΆΠ½Π΅Π½ΠΈΠ΅ 12.4. ΠœΡŒΡŽΡ‚Π΅ΠΊΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°

Π”Π°Π»Π΅Π΅ приводится Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° модификация исходной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ thread1.с, Π½ΠΎ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ измСнСнная. На этот Ρ€Π°Π· Π²Ρ‹ ΡƒΠ΄Π΅Π»ΠΈΡ‚Π΅ особоС Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ доступу ΠΊ вашим Π²Π°ΠΆΠ½Ρ‹ΠΌ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌ ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΌΡŒΡŽΡ‚Π΅ΠΊΡ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ²Π΅Ρ€Π΅Π½Π½Ρ‹ΠΌΠΈ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ доступны Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ. Для лСгкости чтСния тСкста ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΌΡ‹ пропустили Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ ошибок ΠΏΡ€ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π°Ρ… ΠΈΠ· ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ°, Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ. Π’ Ρ€Π°Π±ΠΎΡ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ Π²Ρ‹ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΡΡ‚ΡŒ эти Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹Π΅ значСния. Π”Π°Π»Π΅Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Π½ΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ thread4.c.

#includeΒ &lt;stdio.h&gt;

#includeΒ &lt;unistd.h&gt;

#includeΒ &lt;stdlib.h&gt;

#includeΒ &lt;string.h&gt;

#includeΒ &lt;pthread.h&gt;

#includeΒ &lt;semaphore.h&gt;

void *thread_function(void *arg);

pthread_mutex_t work_mutex;Β /* Π·Π°Ρ‰ΠΈΡ‰Π°Π΅Ρ‚ work_area ΠΈ time_to_exit */

#define WORK_SIZE 1024

char work_area[WORK_SIZE];

int time_to_exit = 0;

int main() {

Β int res;

Β pthread_t a_thread;

Β void *thread_result;

Β res = pthread_mutex_init(&amp;work_mutex, NULL);

Β if (res != 0) {

Β  perror(&quot;Mutex initialization failed&quot;);

Β Β exit(EXIT_FAILURE);

Β }

Β res pthread_create(&amp;a_thread, NULL, thread_function, NULL);

Β if (res != 0) {

Β  perror(&quot;Thread creation failed&quot;);

Β Β exit(EXIT_FAILURE);

Β }

Β pthread_mutex_lock(&amp;work_mutex);

Β printf(&quot;Input same text. Enter 'end' to finish\n&quot;);

Β while (!time_to_exit) {

Β  fgets (work_area, WORK_SIZE, stdin);

Β Β pthread_mutex_unlock(&amp;work_mutex);

Β Β while(1) {

Β Β  pthread_mutex_lock(&amp;work_mutex);

Β  Β if (work_area[0] != '\0') {

Β Β Β  pthread_mutex_unlock(&amp;work_mutex);

Β Β Β  sleep(1);

Β Β  } else {

Β Β  Β break;

Β Β  }

Β  }

Β }

Β pthread_mutex_unlock(&amp;work_mutex);

Β printf(&quot;\nWaiting for thread to finish...\n&quot;);

Β res = pthread_join(a_thread, &amp;thread_result);

Β if (res ! = 0) {

Β  perror(&quot;Thread join failed&quot;);

Β Β exit(EXIT_FAILURE);

Β }

Β printf(&quot;Thread joined\n&quot;);

Β pthread_mutex_destroy(&amp;work_mutex);

Β exit(EXIT_SUCCESS);

}

void *thread_function(void *arg) {

Β sleep(1);

Β pthread_mutex_lock(&amp;work_mutex);

Β while(strncmp(&quot;end&quot;, work_area, 3) ! = 0) {

Β  printf(&quot;You input %d characters\n&quot;, strlen(work_area)-1);

Β Β work_area[0] = '\0';

Β  pthread_mutex_unlock(&amp;work_mutex);

Β Β sleep(1);

Β  pthread_mutex_lock(&amp;work_mutex);

Β Β while (work_area[0] == '\0') {

Β Β  pthread_mutex_unlock(&amp;work_mutex);

Β  Β sleep(1);