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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° сСтСвых ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 232

Автор Уильям БтивСнс

Листинг 30.12. Ѐункция my_lock_init: Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Ρ„Π°ΠΉΠ»Π°

//server/lock_fcntl.c

 1 #include "unp.h"


 2 static struct flock lock_it, unlock_it;

 3 static int lock_fd = -1;

 4 /* fcntl() Π½Π΅ выполнится, Ссли Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° функция my_lock_init() */


 5 void

 6 my_lock_init(char *pathname)

 7 {

 8  char lock_file[1024];


 9  /* ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ строку Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π³ΠΎ процСсса Π½Π° случай, Ссли это константа */

10  strncpy(lock_file, pathname, sizeof(lock_file));

11  lock_fd = Mkstemp(lock_file);


12  Unlink(lock_file); /* Π½ΠΎ lock_fd остаСтся ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ */


13  lock_it.l_type = F_WRLCK;

14  lock_it.l_whence = SEEK_SET;

15  lock_it.l_start = 0;

16  lock_it.l_len = 0;


17  unlock_it.l_type = F_UNLCK;

18  unlock_it.l_whence = SEEK_SET;

19  unlock_it.l_start = 0;

20  unlock_it.l_len = 0;

21 }

9-12 Π’Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ процСсс Π·Π°Π΄Π°Π΅Ρ‚ шаблон для ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_lock_init, ΠΈ функция mkstemp Π½Π° основС этого шаблона создаСт ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠ΅ имя Ρ„Π°ΠΉΠ»Π°. Π—Π°Ρ‚Π΅ΠΌ создаСтся Ρ„Π°ΠΉΠ» с этим ΠΈΠΌΠ΅Π½Π΅ΠΌ ΠΈ сразу ΠΆΠ΅ вызываСтся функция unlink, Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ Ρ‡Π΅Π³ΠΎ имя Ρ„Π°ΠΉΠ»Π° удаляСтся ΠΈΠ· ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π°. Если Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ впослСдствии ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ сбой, Ρ‚ΠΎ Ρ„Π°ΠΉΠ» исчСзнСт Π±Π΅Π·Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π½ΠΎ. Но ΠΏΠΎΠΊΠ° ΠΎΠ½ остаСтся ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… процСссах (ΠΈΠ½Ρ‹ΠΌΠΈ словами, ΠΏΠΎΠΊΠ° счСтчик ссылок для этого Ρ„Π°ΠΉΠ»Π° большС нуля), сам Ρ„Π°ΠΉΠ» Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»Π΅Π½. (ΠžΡ‚ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ΠΌ ΠΈΠΌΠ΅Π½ΠΈ Ρ„Π°ΠΉΠ»Π° ΠΈΠ· ΠΊΠ°Ρ‚Π°Π»ΠΎΠ³Π° ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ΠΌ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° сущСствуСт Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Π°Ρ Ρ€Π°Π·Π½ΠΈΡ†Π°.)

13-20 Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ся Π΄Π²Π΅ структуры flock: ΠΎΠ΄Π½Π° для блокирования Ρ„Π°ΠΉΠ»Π°, другая для снятия Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Π‘Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ начинаСтся с нуля (l_whence =SEEK_SET, l_start=0). Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ l_len Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ вСсь Ρ„Π°ΠΉΠ». Π’ этот Ρ„Π°ΠΉΠ» Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ записываСтся (Π΅Π³ΠΎ Π΄Π»ΠΈΠ½Π° всСгда Ρ€Π°Π²Π½Π° Π½ΡƒΠ»ΡŽ), Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π² любом случаС Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ ядром.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

Π‘Π½Π°Ρ‡Π°Π»Π° Π°Π²Ρ‚ΠΎΡ€ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π» эти структуры ΠΏΡ€ΠΈ объявлСнии:

static struct flock lock_it = { F_WRLCK, 0, 0, 0, 0 };

static struct flock unlock_it = { F_UNLCK, 0, 0, 0, 0 };

Π½ΠΎ Ρ‚ΡƒΡ‚ Π²ΠΎΠ·Π½ΠΈΠΊΠ»ΠΈ Π΄Π²Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹: Ρƒ нас Π½Π΅Ρ‚ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ, Ρ‡Ρ‚ΠΎ константа SEEK_SET Ρ€Π°Π²Π½Π° Π½ΡƒΠ»ΡŽ, Π½ΠΎ, Ρ‡Ρ‚ΠΎ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ, стандарт POSIX Π½Π΅ Ρ€Π΅Π³Π»Π°ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ порядок располоТСния ΠΏΠΎΠ»Π΅ΠΉ этой структуры. POSIX Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Π΅ поля ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ Π² структурС. POSIX Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ порядка слСдования ΠΏΠΎΠ»Π΅ΠΉ структуры, Π° Ρ‚Π°ΠΊΠΆΠ΅ допускаСт Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π² Π½Π΅ΠΉ ΠΏΠΎΠ»Π΅ΠΉ, Π½Π΅ относящихся ΠΊ стандарту POSIX. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΠΎΠ³Π΄Π° трСбуСтся ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эту структуру (Ссли Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ всС поля нулями), это приходится Π΄Π΅Π»Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· фактичСский ΠΊΠΎΠ΄ Π‘, Π° Π½Π΅ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€Π° ΠΏΡ€ΠΈ объявлСнии структуры.

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ ΠΈΠ· этого ΠΏΡ€Π°Π²ΠΈΠ»Π° являСтся ситуация, ΠΊΠΎΠ³Π΄Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ структуры обСспСчиваСтся Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ. НапримСр, ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Π² POSIX Π² Π³Π»Π°Π²Π΅ 26 ΠΌΡ‹ писали:

pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;

Π’ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… pthread_mutex_t β€” это нСкая структура, Π½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ‚ΠΎΡ€ прСдоставляСтся Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ для Ρ€Π°Π·Π½Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ.

Π’ листингС 30.13 ΠΏΠΎΠΊΠ°Π·Π°Π½Ρ‹ Π΄Π²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ ΠΈ ΡΠ½ΠΈΠΌΠ°ΡŽΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ с Ρ„Π°ΠΉΠ»Π°. Они ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fcntl, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ структуры, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ Π² листингС 30.12.

Листинг 30.13. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ my_lock_wait (установлСниС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°) ΠΈ my_lock_release (снятиС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ„Π°ΠΉΠ»Π°)

//server/lock_fcntl.c

23 void

24 my_lock_wait()

25 {

26  int rc;

27  while ((rc = fcntl(lock_ld, F_SETLKW, &lock_it)) < 0 {

28   if (errno == EINTR)

29    continue;

30   else

31    errsys("fcntl error for my_lock_wait");

32  }

33 }


34 void

35 my_lock_release()

36 {

37  if (fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0)

38   errsys("fcntl error for my_lock_release");

39 }

Новая вСрсия нашСго сСрвСра с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ процСссов Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎΠ΄ SVR4, гарантируя, Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ Π² Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept. Бравнивая строки 2 ΠΈ 3 Π² Ρ‚Π°Π±Π». 30.1 (Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ для сСрвСров Digital Unix ΠΈ BSD/OS), ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ врСмя, Π·Π°Ρ‚Ρ€Π°Ρ‡ΠΈΠ²Π°Π΅ΠΌΠΎΠ΅ Ρ†Π΅Π½Ρ‚Ρ€Π°Π»ΡŒΠ½Ρ‹ΠΌ процСссором Π½Π° ΡƒΠ·Π»Π΅ сСрвСра.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

Π’Π΅Π±-сСрвСр Apache (http://www.apache.org) ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ Ρ‚Π΅Ρ…Π½ΠΎΠ»ΠΎΠ³ΠΈΡŽ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ пороТдСния процСссов, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Ссли позволяСт рСализация, всС Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ процСссы Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ accept, ΠΈΠ½Π°Ρ‡Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Ρ„Π°ΠΉΠ»Π° для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ Π²Ρ‹Π·ΠΎΠ²Π° accept.

Π­Ρ„Ρ„Π΅ΠΊΡ‚ наличия слишком большого количСства Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΡ… процСссов

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

РаспрСдСлСниС клиСнтских соСдинСний ΠΌΠ΅ΠΆΠ΄Ρƒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ процСссами

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΡƒΡŽ Π² листингС 30.10, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΈΡΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ распрСдСлСниС клиСнтских запросов ΠΌΠ΅ΠΆΠ΄Ρƒ свободными Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌΠΈ процСссами. Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Π½ Π² Ρ‚Π°Π±Π». 30.2. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Π°Ρ систСма распрСдСляСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Ρ„Π°ΠΉΠ»Π° Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΌΠΈ процСссами, ΠΈ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½ΠΎ для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… протСстированных Π½Π°ΠΌΠΈ систСм.

30.8. Π‘Π΅Ρ€Π²Π΅Ρ€ TCP с ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ΠΌ процСссов ΠΈ Π·Π°Ρ‰ΠΈΡ‚ΠΎΠΉ Π²Ρ‹Π·ΠΎΠ²Π° accept ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

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

Ѐункция main остаСтся Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅, Ρ‚ΠΎ ΠΆΠ΅ относится ΠΊ функциям child_make ΠΈ child_main. ΠœΠ΅Π½ΡΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Ρ€ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²Π»ΡΡŽΡ‰ΠΈΠ΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ процСссами, Π²ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, трСбуСтся Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ это Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² раздСляСмой процСссами области памяти, Π° Π²ΠΎ-Π²Ρ‚ΠΎΡ€Ρ‹Ρ…, Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ процСссами.

ΠŸΠ Π˜ΠœΠ•Π§ΠΠΠ˜Π•

ВрСбуСтся Ρ‚Π°ΠΊΠΆΠ΅, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π»Π° Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ PTHREAD_PROCESS_SHARED.

БущСствуСт нСсколько способов раздСлСния памяти ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ процСссами, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ описываСм Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ Ρ‚ΠΎΠΌΠ΅[2] Π΄Π°Π½Π½ΠΎΠΉ сСрии. Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ mmap с устройством /dev/zero, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ с ядрами Solaris ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ ядрами SVR4. Π’ листингС 30.14 ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Ρ‚ΠΎΠ»ΡŒΠΊΠΎ функция my_lock_init.

Листинг 30.14. Ѐункция my_lock_init: использованиС Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, относящимися ΠΊ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ процСссам (тСхнология Pthread)

//server/lock_pthread.c

 1 #include "unpthread.h"


 2 #include <sys/mman.h>

 3 static pthread_mutex_t *mptr; /* фактичСски Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π±ΡƒΠ΄Π΅Ρ‚

                                    Π² совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ памяти */


 4 void

 5 my_lock_init(char *pathname)

 6 {

 7  int fd;

 8  pthread_mutexattr_t mattr;


 9  fd = Open("/dev/zero", O_RDWR, 0);


10  mptr = Mmap(0, sizeof(pthread_mutex_t), PROT_READ | PROT_WRITE,

11   MAP_SHARED, fd, 0);

12  Close(fd);


13  Pthread_mutexattr_init(&mattr);

14  Pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);

15  Pthread_mutex_init(mptr, &mattr);

16 }

9-12 ΠœΡ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ (open) Ρ„Π°ΠΉΠ» /dev/zero, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ mmap. ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π±Π°ΠΉΡ‚ΠΎΠ² (Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ) β€” это Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ pthread_mutex_t. Π—Π°Ρ‚Π΅ΠΌ дСскриптор закрываСтся, Π½ΠΎ для нас это Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ значСния, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ„Π°ΠΉΠ» ΡƒΠΆΠ΅ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ.

13-15 Π’ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Ρ€Π°Π½Π΅Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ… Π²Π·Π°ΠΈΠΌΠ½Ρ‹Ρ… ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ Pthread ΠΌΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»ΠΈ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ статичСскиС Π²Π·Π°ΠΈΠΌΠ½Ρ‹Π΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ константу PTHREAD_MUTEX_INITIALIZER (см., Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, листинг 26.12). Но располагая Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π² совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ памяти, ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Pthreads, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡΠΎΠΎΠ±Ρ‰ΠΈΡ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΠΎ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ сСмафора Π² совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ памяти ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ для синхронизации ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², относящихся ΠΊ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌ процСссам. ΠœΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ структуру pthread_mutexattr_t Π·Π°Π΄Π°Π²Π°Π΅ΠΌΡ‹ΠΌΠΈ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, Π° Π·Π°Ρ‚Π΅ΠΌ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° PTHREAD_PROCESS_SHARED. (По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ этого Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π° Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ PTHREAD_PROCESS_PRIVATE, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°Π΅Ρ‚ использованиС Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса.) Π—Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ² pthread_mutex_init ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΌΠΈ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π°ΠΌΠΈ.