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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«UNIX: взаимодСйствиС процСссов». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 65

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

Π§Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, Ссли ΠΌΡ‹ Π²Ρ‹Π·ΠΎΠ²Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sem_open, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‰ΡƒΡŽ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ‚ΠΈΠΏ sem_t, Π° Π·Π°Ρ‚Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅ΠΌ fork? Π’ описании Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ fork Π² стандартС Posix.1 говорится, Ρ‡Ρ‚ΠΎ «всС ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Π΅ Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΌ процСссом сСмафоры Π±ΡƒΠ΄ΡƒΡ‚ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ ΠΈ Π² Π΄ΠΎΡ‡Π΅Ρ€Π½Π΅ΠΌ процСссС». Π­Ρ‚ΠΎ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½ΠΈΠΆΠ΅ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ Π²Π΅Ρ€Π΅Π½:

sem_t *mutex; /* Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ, ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ fork() */

…

/* Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс создаСт ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафор */

mutex = Sem_open(Px_ipc_name(NAME), O_CREAT | O_EXCL, FILE_MODE, 0);

if ((childpid = Fork()) == 0) {

 /* Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΉ процСсс */

 β€¦

 Sem_wait(mutex);

 β€¦

}

/* Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ процСсс */

…

Sem_post(mutex);

…

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

ΠŸΡ€ΠΈΡ‡ΠΈΠ½Π°, ΠΏΠΎ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ слСдуСт Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚ΡŒΡΡ ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ сСмафоров ΠΏΡ€ΠΈ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ процСссов, Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ состояниС сСмафора ΠΌΠΎΠΆΠ΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° sem_t, Π½ΠΎ для Π΅Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ другая информация (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, дСскрипторы Ρ„Π°ΠΉΠ»ΠΎΠ²). Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Π³Π»Π°Π²Π΅ ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ сСмафоры System V ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ ΠΈΡ… цСлочислСнными ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π°ΠΌΠΈ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ semget. Π›ΡŽΠ±ΠΎΠΉ процСсс, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ извСстСн ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€, ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ сСмафору. Вся информация ΠΎ сСмафорС System V хранится Π² ядрС, Π° цСлочислСнный ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ просто ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½ΠΎΠΌΠ΅Ρ€ сСмафора ядру.

10.13. ΠžΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΡ Π½Π° сСмафоры

Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚ΠΎΠΌ Posix ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π΄Π²Π° ограничСния Π½Π° сСмафоры:

β–  SEM_NSEMS_MAX β€” максимальноС количСство ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹Ρ… сСмафоров для ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса (Posix Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π±Ρ‹Π»ΠΎ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ 256);

β–  SEM_VALUE_MAX β€” максимальноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора (Posix Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π½Π΅ мСньшС 32767).

Π”Π²Π΅ эти константы ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠΌ Ρ„Π°ΠΉΠ»Π΅ <unistd.h> ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ Π²ΠΎ врСмя выполнСния Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ sysconf, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Π½ΠΈΠΆΠ΅.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° semsysconf

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π² листингС 10.20 Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ sysconf ΠΈ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π΄Π²Π° ограничСния Π½Π° сСмафоры, зависящиС ΠΎΡ‚ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. 

Листинг 10.20. Π’Ρ‹Π·ΠΎΠ² sysconf для получСния ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠΉ Π½Π° сСмафоры

//pxsem/semsysconf.с

1 #include "unpipc.h"


2 int

3 main(int argc, char **argv)

4 {

5  printf("SEM_NSEMS_MAX = %ld, SEM_VALUE_MAX = %ld\n",

6   Sysconf(_SC_SEM_NSEMS_MAX), Sysconf(_SC_SEM_VALUE_MAX));

7  exit(0);

8 }

ΠŸΡ€ΠΈ запускС этой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Π½Π°ΡˆΠΈΡ… Π΄Π²ΡƒΡ… тСстовых систСмах ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

solaris % semsysconf

SEMS_NSEMS_MAX = 2147483647, SEM_VALUE_MAX = 2147483647

alpha % semsysconf

SEMS_NSEMS_MAX = 256, SEM_VALUE_MAX = 32767

10.14. РСализация с использованиСм FIFO

ЗаймСмся Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… сСмафоров Posix с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ°Π½Π°Π»ΠΎΠ² FIFO. Π˜ΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафор рСализуСтся ΠΊΠ°ΠΊ ΠΊΠ°Π½Π°Π» FIFO с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹ΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ. ΠΠ΅ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ количСство Π±Π°ΠΉΡ‚ΠΎΠ² Π² ΠΊΠ°Π½Π°Π»Π΅ соотвСтствуСт Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ сСмафора. Ѐункция sem_post ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ 1 Π±Π°ΠΉΡ‚ Π² ΠΊΠ°Π½Π°Π», a sem_wait считываСт Π΅Π³ΠΎ ΠΎΡ‚Ρ‚ΡƒΠ΄Π° (приостанавливая Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ процСсса, Ссли ΠΊΠ°Π½Π°Π» пуст, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ этого ΠΌΡ‹ ΠΈ Ρ…ΠΎΡ‚ΠΈΠΌ). Ѐункция sem_open создаСт ΠΊΠ°Π½Π°Π» FIFO, Ссли ΡƒΠΊΠ°Π·Π°Π½ Ρ„Π»Π°Π³ O_CREAT; ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ Π΅Π³ΠΎ Π΄Π²Π°ΠΆΠ΄Ρ‹ (ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Π½Π° запись, Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅) ΠΈ ΠΏΡ€ΠΈ создании Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° FIFO ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π² Π½Π΅Π³ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ количСство Π±Π°ΠΉΡ‚ΠΎΠ², ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π² качСствС Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния.

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

Π­Ρ‚ΠΎΡ‚ ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹ Π΄Π°Π½Π½ΠΎΠΉ Π³Π»Π°Π²Ρ‹ содСрТат услоТнСнный ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Ρ‡Ρ‚Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ.

ΠŸΡ€ΠΈΠ²Π΅Π΄Π΅ΠΌ тСкст нашСго Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° semaphore.h, ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‰Π΅Π³ΠΎ Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ sem_t (листинг 10.21).

Листинг 10.21. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΡ‡Π½Ρ‹ΠΉ Ρ„Π°ΠΉΠ» semaphore.h

//my_pxsem_fifo/semaphore.h

1  /* Ρ„ΡƒΠ½Π΄Π°ΠΌΠ΅Π½Ρ‚Π°Π»ΡŒΠ½Ρ‹ΠΉ Ρ‚ΠΈΠΏ */

2  typedef struct {

3   int sem_fd[2]; /* Π΄Π²Π° дСскриптора fd: [0] для чтСния, [1] для записи */

4   int sem_magic; /* магичСскоС число */

5  } mysem_t;


6  #define SEM_MAGIC 0x89674523


7  #ifdef SEM_FAILED

8  #undef SEM_FAILED

9  #define SEM_FAILED ((mysem_t *)(-1)) /* Ρ‡Ρ‚ΠΎΠ±Ρ‹ компилятор Π½Π΅ Π²Ρ‹Π΄Π°Π²Π°Π» ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ*/


10 #endif

Π’ΠΈΠΏ Π΄Π°Π½Π½Ρ‹Ρ… sem_t

1-5 Новая структура Π΄Π°Π½Π½Ρ‹Ρ… содСрТит Π΄Π²Π° дСскриптора, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ для чтСния ΠΈΠ· FIFO, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” для записи. Для Сдинообразия ΠΌΡ‹ Ρ…Ρ€Π°Π½ΠΈΠΌ ΠΎΠ±Π° дСскриптора Π² массивС ΠΈΠ· Π΄Π²ΡƒΡ… элСмСнтов, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ дСскриптор всСгда ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ β€” Π½Π° запись.

ПолС sem_magiс содСрТит Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ SEM_MAGIC, Ссли структура ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π°. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ провСряСтся всСми функциями, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ пСрСдаСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ‚ΠΈΠΏ sem_t, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½ Π±Ρ‹Π» Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ структуру, Π° Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ памяти. ΠŸΡ€ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ сСмафора этому полю присваиваСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ 0. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ хотя ΠΈ Π½Π΅ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π΅Π½, Π½ΠΎ Π΄Π°Π΅Ρ‚ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ошибки ΠΏΡ€ΠΈ написании ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ.

Ѐункция sem_open

Π’ листингС 10.22 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_open, которая создаСт Π½ΠΎΠ²Ρ‹ΠΉ сСмафор ΠΈΠ»ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅Ρ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ.

Листинг 10.22. Ѐункция sem_open

//my_pxsem_fifo/sem_open.с

1  #include "unpipc.h"

2  #include "semaphore.h"

3  #include <stdarg.h> /* для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ списка Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² */


4  mysem_t *

5  mysem_open(const char *pathname, int oflag, …)

6  {

7   int i, flags, save_errno;

8   char c;

9   mode_t mode;

10  va_list ap;

11  mysem_t *sem;

12  unsigned int value;

13  if (oflag & O_CREAT) {

14   va_start(ap, oflag); /* Π°Ρ€ инициализируСтся послСдним Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ */

15   mode = va_arg(ap, va_mode_t);

16   value = va_arg(ap, unsigned int);

17   va_end(ap);

18   if (mkfifo(pathname, mode) < 0) {

19    if (errno == EEXIST && (oflag & O_EXCL) == 0)

20     oflag &= ~O_CREAT; /* ΡƒΠΆΠ΅ сущСствуСт, OK */

21    else

22     return(SEM_FAILED);

23   }

24  }

25  if ((sem = malloc(sizeof(mysem_t))) == NULL)

26   return(SEM_FAILED);

27  sem->sem_fd[0] = sem->sem_fd[1] = –1;

28  if ((sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK)) < 0)

29   goto error;

30  if ((sem->sem_fd[1] = open(pathname, O_WRONLY | O_NONBLOCK)) < 0)

31   goto error;

32  /* ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ Ρ€Π΅ΠΆΠΈΠΌΠ° для sem_fd[0] */

33  if ((flags = fcntl(sem->sem_fd[0], F_GETFL, 0)) < 0)

34   goto error;

35  flags &= ~O_NONBLOCK;

36  if (fcntl(sem->sem_fd[0], F_SETFL, flags) < 0)

37   goto error;

38  if (oflag & O_CREAT) { /* инициализация сСмафора */

39   for (i = 0; i < value; i++)

40    if (write(sem->sem_fd[1], &c, 1) != 1)

41   goto error;

42  }

43  sem->sem_magic = SEM_MAGIC;

44  return(sem);

45 error:

46  save_errno = errno;

47  if (oflag & O_CREAT)

48   unlink(pathname); /* Ссли ΠΌΡ‹ создали FIFO */

49  close(sem->sem_fd[0]); /* ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ */

50  close(sem->sem_fd[1]); /* ΠΈΠ³Π½ΠΎΡ€ΠΈΡ€ΡƒΠ΅ΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ */

51  free(sem);

52  errno = save_errno;

53  return(SEM_FAILED);

54 }

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ sсСмафора

13-17 Если ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΡƒΠΊΠ°Π·Π°Π½ Ρ„Π»Π°Π³ O_CREAT, Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½ΠΎ Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°, Π° Π½Π΅ Π΄Π²Π°. ΠœΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ va_start, послС Ρ‡Π΅Π³ΠΎ пСрСмСнная Π°Ρ€ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° послСдний явно ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ (oflag). Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Π°Ρ€ ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ va_arg для получСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅Π³ΠΎ ΠΈ Ρ‡Π΅Ρ‚Π²Π΅Ρ€Ρ‚ΠΎΠ³ΠΎ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π Π°Π±ΠΎΡ‚Ρƒ со списком Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹ ΠΈ использованиС нашСго Ρ‚ΠΈΠΏΠ° va_mode_t ΠΌΡ‹ обсуТдали Π² связи с листингом 5.17.

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ°Π½Π°Π»Π° FIFO

18-23 БоздаСтся Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠ°Π½Π°Π» FIFO, имя ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±Ρ‹Π»ΠΎ ΡƒΠΊΠ°Π·Π°Π½ΠΎ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Как ΠΌΡ‹ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΈ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 4.6, эта функция Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ EEXIST, Ссли ΠΊΠ°Π½Π°Π» ΡƒΠΆΠ΅ сущСствуСт. Если ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ sem_open Ρ„Π»Π°Π³ O_EXCL Π½Π΅ Π±Ρ‹Π» ΡƒΠΊΠ°Π·Π°Π½, ΠΌΡ‹ пропускаСм эту ΠΎΡˆΠΈΠ±ΠΊΡƒ; Π½ΠΎ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ этот ΠΊΠ°Π½Π°Π», Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΌΡ‹ ΠΏΡ€ΠΈ этом сбрасываСм Ρ„Π»Π°Π³ O_CREAT.

Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти ΠΏΠΎΠ΄ Ρ‚ΠΈΠΏ sem_t ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ FIFO Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ ΠΈ запись

25-37 ΠœΡ‹ выдСляСм мСсто для Ρ‚ΠΈΠΏΠ° sem_t, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ содСрТит Π΄Π²Π° дСскриптора. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π΄Π²Π°ΠΆΠ΄Ρ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΠΊΠ°Π½Π°Π» FIFO: ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π· Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ β€” Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° запись. ΠŸΡ€ΠΈ этом ΠΌΡ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΠΌ блокирования ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ open, поэтому ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„Π»Π°Π³ΠΈ O_NONBLOCK ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для чтСния (вспомнитС Ρ‚Π°Π±Π». 4.1). ΠœΡ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅ΠΌ Ρ„Π»Π°Π³ O_NONBLOCK ΠΏΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ ΠΊΠ°Π½Π°Π»Π° Π½Π° запись, Π½ΠΎ это ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½ΠΎ для обнаруТСния пСрСполнСния (Π½Π° Ρ‚ΠΎΡ‚ случай, Ссли ΠΌΡ‹ попытаСмся Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ большС, Ρ‡Π΅ΠΌ позволяСт PIPE_BUF). ПослС открытия ΠΊΠ°Π½Π°Π»Π° ΠΌΡ‹ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π°Π΅ΠΌ Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ Ρ€Π΅ΠΆΠΈΠΌ для дСскриптора, ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ³ΠΎ Π½Π° Ρ‡Ρ‚Π΅Π½ΠΈΠ΅.

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ значСния созданного сСмафора

38-42 Если ΠΌΡ‹ создали сСмафор, Π΅Π³ΠΎ Π½ΡƒΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ, записав Π² ΠΊΠ°Π½Π°Π» FIFO value Π±Π°ΠΉΡ‚ΠΎΠ². Если ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ value ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ PIPE_BUF, Π²Ρ‹Π·ΠΎΠ² write послС пСрСполнСния FIFO Π²Π΅Ρ€Π½Π΅Ρ‚ ΠΎΡˆΠΈΠ±ΠΊΡƒ с ΠΊΠΎΠ΄ΠΎΠΌ EAGAIN.