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

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

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

33-37 ΠœΡ‹ устанавливаСм Ρ€Π°Π·ΠΌΠ΅Ρ€ созданного Ρ„Π°ΠΉΠ»Π°, записывая Π² Π½Π΅Π³ΠΎ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΡƒΡŽ нулями структуру. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Π·Π½Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ созданный Ρ„Π°ΠΉΠ» ΠΈΠΌΠ΅Π΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ 0, для установки Π΅Π³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ ΠΈΠΌΠ΅Π½Π½ΠΎ write, Π½ΠΎ Π½Π΅ ftruncate, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ, ΠΊΠ°ΠΊ ΠΌΡ‹ ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π΅ΠΌ Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 13.3, Posix Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ ftruncate срабатываСт ΠΏΡ€ΠΈ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ². 

ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ содСрТимого Ρ„Π°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ

38-42 Π€Π°ΠΉΠ» отобраТаСтся Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ mmap. Π­Ρ‚ΠΎΡ‚ Ρ„Π°ΠΉΠ» Π±ΡƒΠ΄Π΅Ρ‚ ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ структуры Ρ‚ΠΈΠΏΠ° sem_t, хотя, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΡ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΠΎΡ‚ΠΎΠ±Ρ€Π°Π·ΠΈΠ»ΠΈ Ρ„Π°ΠΉΠ» Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ, ΠΌΡ‹ обращаСмся ΠΊ Π½Π΅ΠΌΡƒ Ρ‡Π΅Ρ€Π΅Π· ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ mmap, ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ read ΠΈΠ»ΠΈ write.

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ структуры sem_t

43-57 ΠœΡ‹ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌ Ρ‚Ρ€ΠΈ поля структуры sem_t: Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅, ΡƒΡΠ»ΠΎΠ²Π½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафор Posix ΠΌΠΎΠΆΠ΅Ρ‚ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ всСми процСссами с ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌΠΈ ΠΏΡ€Π°Π²Π°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ извСстно Π΅Π³ΠΎ имя, ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ PTHREAD_PROCESS_SHARED. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΈΡ‚ΡŒ это для Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ, Π½ΡƒΠΆΠ½ΠΎ сначала ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹, Π²Ρ‹Π·Π²Π°Π² pthread_mutexattr_init, Π·Π°Ρ‚Π΅ΠΌ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ совмСстного использования ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ, Π²Ρ‹Π·Π²Π°Π² pthread_mutexattr_setpshared, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ pthread_mutex_init. АналогичныС дСйствия придСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈ для условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ. НСобходимо Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… хранятся Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹, ΠΏΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибок.

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

58-61 НаконСц ΠΌΡ‹ ΠΏΠΎΠΌΠ΅Ρ‰Π°Π΅ΠΌ Π² Ρ„Π°ΠΉΠ» Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора. ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΌΡ‹ сравниваСм Π΅Π³ΠΎ с максимально Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ сСмафора, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΎ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ sysconf (Ρ€Π°Π·Π΄Π΅Π» 10.13).

Бброс Π±ΠΈΡ‚Π° user-execute

62-67 ПослС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ сСмафора ΠΌΡ‹ сбрасываСм Π±ΠΈΡ‚ user-execute. Π­Ρ‚ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ сСмафор Π±Ρ‹Π» ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½. Π—Π°Ρ‚Π΅ΠΌ ΠΌΡ‹ Π·Π°ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ close, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ½ ΡƒΠΆΠ΅ Π±Ρ‹Π» ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΈ Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π΄Π΅Ρ€ΠΆΠ°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ.

Π’ листингС 10.29 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Π²Ρ‚ΠΎΡ€ΠΎΠΉ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_open. Π—Π΄Π΅ΡΡŒ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ситуация Π³ΠΎΠ½ΠΎΠΊ, обрабатываСмая Ρ‚Π°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ ΠΎΠ±ΡΡƒΠΆΠ΄Π°Π²ΡˆΠ°ΡΡΡ Π² связи с листингом 5.19.

Листинг 10.29. Ѐункция sem_open: вторая ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π°

//my_pxsem_mmap/sem_open.с

69  exists:

70   if ((fd = open(pathname, O_RDWR)) < 0) {

71    if (errno == ENOENT && (oflag & O_CREAT))

72     goto again;

73    goto err;

74   }

75   sem = mmap(NULL, sizeof(mysem_t), PROT_READ | PROT_WRITE,

76    MAP_SHARED, fd, 0);

77   if (sem == MAP_FAILED)

78    goto err;

79   /* удостовСримся, Ρ‡Ρ‚ΠΎ инициализация Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½Π° */

80   for (i = 0; i < MAX TRIES; i++) {

81    if (stat(pathname, &statbuff) == –1) {

82     if (errno == ENOENT && (oflag & O_CREAT)) {

83      close(fd);

84      goto again;

85     }

86     goto err;

87    }

88    if ((statbuff.st_mode & S_IXUSR) == 0) {

89     close(fd);

90     sem->sem_magic = SEM_MAGIC;

91     return(sem);

92    }

93    sleep(1);

94   }

95   errno = ETIMEDOUT;

96   goto err;

97  pthreaderr:

98   errno = i;

99  err:

100  /* Π½Π΅ Π΄Π°Π΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π°ΠΌ unlink ΠΈ munmap ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠ΄ errno */

101  save_errno = errno;

102  if (created)

103   unlink(pathname);

104  if (sem != MAP_FAILED)

105   munmap(sem, sizeof(mysem_t));

106  close(fd);

107  errno = save_errno;

108  return(SEM_FAILED);

109 }

ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π³ΠΎ сСмафора

69-78 Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅ΠΌ Π½Π°ΡˆΡƒ Ρ€Π°Π±ΠΎΡ‚Ρƒ, Ссли Π»ΠΈΠ±ΠΎ Π½Π΅ ΡƒΠΊΠ°Π·Π°Π½ Ρ„Π»Π°Π³ O_CREAT, Π»ΠΈΠ±ΠΎ ΠΎΠ½ ΡƒΠΊΠ°Π·Π°Π½, Π½ΠΎ сСмафор ΡƒΠΆΠ΅ сущСствуСт. Π’ Ρ‚ΠΎΠΌ ΠΈ Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ случаС ΠΌΡ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ сСмафор. ΠœΡ‹ ΠΎΡ‚ΠΊΡ€Ρ‹Π²Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ open для чтСния ΠΈ записи, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌ Π΅Π³ΠΎ содСрТимоС Π² адрСсноС пространство процСсса Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ mmap.

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

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π² Posix.1 сказано, Ρ‡Ρ‚ΠΎ Β«ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ копиям сСмафора ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π½Π΅ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΒ». Если ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафор Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Ρ‡Π΅Ρ€Π΅Π· ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Ρ„Π°ΠΉΠ»Π° Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ, ΠΎΠ½ отобраТаСтся Π² адрСсноС пространство всСх процСссов, Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΠ½ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚. Π­Ρ‚ΠΎ осущСствляСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ sem_open для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ процСсса Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. ИзмСнСния, сдСланныС ΠΎΠ΄Π½ΠΈΠΌ процСссом (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ счСтчика сСмафора), становятся доступны Π΄Ρ€ΡƒΠ³ΠΈΠΌ процСссам Ρ‡Π΅Ρ€Π΅Π· ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ. Если ΠΌΡ‹ сдСлаСм свою ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ копию структуры sem_t, ΠΎΠ½Π° ΡƒΠΆΠ΅ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ‰Π΅ΠΉ для всСх процСссов. Π₯отя Π½Π°ΠΌ ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΡΡ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ (Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с сСмафором Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Ρ‚ΡŒ ошибок, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅ Π΄ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° sem_close, которая Π½Π΅ смоТСт ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ для ΠΊΠΎΠΏΠΈΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°), с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ процСссами ΠΌΡ‹ ΠΏΡ€ΠΈ этом Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ смоТСм. Однако Π·Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅ (Ρ‚Π°Π±Π». 1.4), Ρ‡Ρ‚ΠΎ области памяти с ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹ΠΌΠΈ Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠΌ процСссам ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ fork, поэтому созданиС ΠΊΠΎΠΏΠΈΠΈ сСмафора ядром ΠΏΡ€ΠΈ ΠΏΠΎΡ€ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ процСсса ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚. 

УдостовСримся, Ρ‡Ρ‚ΠΎ сСмафор ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½

79-96 ΠœΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΏΠΎΠ΄ΠΎΠΆΠ΄Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° сСмафор Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½ (Ссли нСсколько ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΡ‹Ρ‚Π°ΡŽΡ‚ΡΡ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ сСмафор ΠΏΡ€ΠΈΠ±Π»ΠΈΠ·ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ). Для этого ΠΌΡ‹ Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ stat ΠΈ провСряСм Π±ΠΈΡ‚Ρ‹ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ Ρ„Π°ΠΉΠ»Π° (ΠΏΠΎΠ»Π΅ st_mode структуры stat). Если Π±ΠΈΡ‚ user-execute снят, структура ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π°.

Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ ΠΊΠΎΠ΄ΠΎΠ² ошибок

97-108 ΠŸΡ€ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΈΠΈ ошибки Π½ΡƒΠΆΠ½ΠΎ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π΅Π΅ ΠΊΠΎΠ΄.

Ѐункция sem_close

Π’ листингС 10.30 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст нашСй Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_close, которая просто Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ munmap для ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ Π² ΠΏΠ°ΠΌΡΡ‚ΡŒ Ρ„Π°ΠΉΠ»Π°. Если Π²Ρ‹Π·Π²Π°Π²ΡˆΠΈΠΉ процСсс ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±Ρ‹Π» Ρ€Π°Π½Π΅Π΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ sem_open, ΠΎΠ½ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ сигнал SIGSEGV.

Листинг 10.30. Ѐункция sem_close

//my_pxsem_mmap/sem_close. с

1  #include "unpipc.h"

2  #include "semaphore.h"


3  int

4  mysem_close(mysem_t *sem)

5  {

6   if (sem->sem_magic != SEM_MAGIC) {

7    errno = EINVAL;

8    return(-1);

9   }

10  if (munmap(sem, sizeof(mysem_t)) == –1)

11  return(-1);

12  return(0);

13 }

Ѐункция sem_unlink

ВСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_unlink ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ Π² листингС 10.31. Она просто удаляСт Ρ„Π°ΠΉΠ», Ρ‡Π΅Ρ€Π΅Π· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π΄Π°Π½Π½Ρ‹ΠΉ сСмафор, вызывая Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ unlink.

Листинг 10.31. Ѐункция sem_unlink

//my_pxsem_mmap/sem_unlink.с

1 #include "unpipc.h"

2 #include "semaphore.h"


3 int

4 mysem_unlink(const char *pathname)

5 {

6  if (unlink(pathname) == –1)

7   return(-1);

8  return(0);

9 }

Ѐункция sem_post

Π’ листингС 10.32 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_post, которая ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора, возобновляя Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ всСх процСссов, Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ этого события.

Листинг 10.32. Ѐункция sem_post

//my_pxsem_mmap/sem_post.с

1  #include "unpipc.h"

2  #include "semaphore.h"


3  int

4  mysem_post(mysem_t *sem)

5  {

6   int n;

7   if (sem->sem_magic != SEM_MAGIC) {

8    errno = EINVAL;

9    return(-1);

10  }

11  if ((n = pthread_mutex_lock(&sem->sem_mutex)) != 0) {

12   errno = n;

13   return(-1);

14  }

15  if (sem->sem_count == 0)

16   pthread_cond_signal(&sem->sem_cond);

17  sem->sem_count++;

18  pthread_mutex_unlock(&sem->sem_mutex);

19  return(0);

20 }

11-18 ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ со структурой, Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора измСняСтся с 0 Π½Π° 1, Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ pthread_cond_signal, Ρ‡Ρ‚ΠΎΠ±Ρ‹ возобновилось Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· процСссов, зарСгистрированных Π½Π° ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΏΠΎ Π΄Π°Π½Π½ΠΎΠΉ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ.

Ѐункция sem_wait

Π’ листингС 10.33 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ тСкст Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_wait, которая ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ измСнСния значСния сСмафора с 0 Π½Π° ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅, послС Ρ‡Π΅Π³ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅Ρ‚ Π΅Π³ΠΎ Π½Π° 1.

Листинг 10.33. Ѐункция sem_wait

//my_pxsem_mmap/sem_wait.с

1  #include "unpipc.h"

2  #include "semaphore.h"


3  int

4  mysem_wait(mysem_t *sem)

5  {

6   int n;

7   if (setn->sem_magic != SEM_MAGIC) {

8    errno = EINVAL;

9    return(-1);

10  }

11  if ((n = pthread_mutex_lock(&sem->sem_mutex)) != 0) {

12   errno = n;

13   return(-1);

14  }

15  while (sem->sem_count == 0)

16   pthread_cond_wait(&sem->sem_cond, &sem->sem_mutex);

17  sem->sem_count--;

18  pthread_mutex_unlock(&sem->sem_mutex);

19  return(0);

20 }

11-18 ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с сСмафором, Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅. Если Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора 0, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ процСсса приостанавливаСтся Π² Π²Ρ‹Π·ΠΎΠ²Π΅ pthread_cond_wait Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π΄Ρ€ΡƒΠ³ΠΎΠΉ процСсс Π½Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ pthread_cond_signal для этого сСмафора, ΠΈΠ·ΠΌΠ΅Π½ΠΈΠ² Π΅Π³ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ с 0 Π½Π° 1. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ становится Π½Π΅Π½ΡƒΠ»Π΅Π²Ρ‹ΠΌ, ΠΌΡ‹ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅ΠΌ Π΅Π³ΠΎ Π½Π° 1 ΠΈ Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅.