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

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

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

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°, привСдСнная Π² листингС 5.1, ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΡƒ совмСстного использования памяти.

Листинг 5.1. (shm.c) ΠŸΡ€ΠΈΠΌΠ΅Ρ€ совмСстного использования памяти

#include <stdio.h>

#include <sys/shm.h>

#include <sys/stat.h>


int main() {

 int segment_id;

 char* shared_memory;

 struct shmid_ds shmbuffer;

 int segment_size;

 const int shared_segment_size = 0x6400;


 /* Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ сСгмСнта. */

 segment_id =

  shmget(IPC_PRIVATE, shared_segment_size,

  IPC_CREAT | IPC_EXCL | S_IRUSR | S_IWUSR);

 /* ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сСгмСнта. */

 shared_memory = (char*)shmat(segment_id, 0, 0);

 printf("shared memory attached at address %p\n",

  shared_memory);

 /* ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° сСгмСнта. */

 shmctl(segment_id, IPC_STAT, &shmbuffer);

 segment_size = shmbuffer.shm_segsz;

 printf("segment size: %d\n", segment_size);

 /* Π—Π°ΠΏΠΈΡΡŒ строки Π² сСгмСнт. */

 sprintf(shared_memory, "Hello, world.");

 /* ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сСгмСнта. */

 shmdt(shared_memory);


 /* ΠŸΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠ΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сСгмСнта, Π½ΠΎ ΠΏΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ адрСсу! */

 shared_memory =

  (char*)shmat(segment_id, (void*) 0x5000000, 0);

 printf("shared memory reattached at address %p\n",

  shared_memory);

 /* ΠžΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ строки, хранящСйся Π² совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠΉ

    памяти. */

 printf("%s\n", shared_memory);

 /* ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сСгмСнта. */

 shmdt(shared_memory);

 /* ОсвобоТдСниС сСгмСнта. */

 shmctl(segment_id, IPC_RMID, 0);

 return 0;

}

5.1.7. ΠžΡ‚Π»Π°Π΄ΠΊΠ°

Команда ipcs Π²Ρ‹Π΄Π°Π΅Ρ‚ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΎ взаимодСйствии процСссов, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ свСдСния ΠΎ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… сСгмСнтах (для этого слСдуСт Π·Π°Π΄Π°Ρ‚ΡŒ Ρ„Π»Π°Π³ -m). НапримСр, Π² ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ Π½ΠΈΠΆΠ΅ случаС сообщаСтся ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΠΎΠΉ сСгмСнт, с Π½ΠΎΠΌΠ΅Ρ€ΠΎΠΌ 1627649:

% ipcs -m

-------- Shared Memory Segments --------

key        shmid   owner perms bytes nattch status

0x00000000 1627649 user  640   25600 0

Если этот сСгмСнт Π±Ρ‹Π» ΠΏΠΎ ошибкС "Π·Π°Π±Ρ‹Ρ‚" ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ, Π΅Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ipcrm:

% ipcrm shm 1627649

5.1.8. ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π²Ρ‹Π±ΠΎΡ€Π°

Благодаря совмСстному использованию памяти ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ€Π³Π°Π½ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ быстроС двустороннСС взаимодСйствиС ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ числа процСссов. Π›ΡŽΠ±ΠΎΠΉ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ смоТСт ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚ΡŒ доступ ΠΊ сСгмСнтам памяти для чтСния/записи, Π½ΠΎ для этого ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΌ ΠΏΡ€Π°Π²ΠΈΠ»Π°ΠΌ, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΌ ΠΈΠ·Π±Π΅Π³Π°Ρ‚ΡŒ ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ†ΠΈΠΈ (Ρ‡Ρ‚ΠΎΠ±Ρ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, информация Π½Π΅ оказалась пСрСзаписанной Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Π½Π°). К соТалСнию, Linux Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΠΎΠ½ΠΎΠΏΠΎΠ»ΡŒΠ½Ρ‹ΠΉ доступ ΠΊ сСгмСнту, Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ Π±Ρ‹Π» создан с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Ρ„Π»Π°Π³Π° IPC_PRIVATE.

ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ нСсколько процСссов ΠΌΠΎΠ³Π»ΠΈ совмСстно Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΎΠ±Ρ‰ΠΈΠΌ сСгмСнтом, ΠΎΠ½ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ "Π΄ΠΎΠ³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒΡΡ" ΠΎ Π²Ρ‹Π±ΠΎΡ€Π΅ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»ΡŽΡ‡Π°.

5.2. Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ для процСссов

Как Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΎΡΡŒ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅, процСссы Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ свои усилия ΠΏΡ€ΠΈ совмСстном доступС ΠΊ памяти. ВспомнитС: Π² Ρ€Π°Π·Π΄Π΅Π»Π΅ 4.4.5, "ΠžΠ±Ρ‹Ρ‡Π½Ρ‹Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²Ρ‹Π΅ сСмафоры", Ρ€Π°ΡΡΠΊΠ°Π·Ρ‹Π²Π°Π»ΠΎΡΡŒ ΠΎ сСмафорах, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ счСтчиками, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠΌΠΈ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². Π’ Linux имССтся Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Π°Ρ рСализация сСмафоров (ΠΈΠ½ΠΎΠ³Π΄Π° Π½Π°Π·Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… сСмафорами System V), ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Ρ… для синхронизации процСссов. Π’Π°ΠΊΠΈΠ΅ сСмафоры Π²Ρ‹Π΄Π΅Π»ΡΡŽΡ‚ΡΡ, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ΡΡ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΌ сСгмСнтам памяти. Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° случаСв достаточно ΠΎΠ΄Π½ΠΎΠ³ΠΎ сСмафора, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΎΠ½ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π³Ρ€ΡƒΠΏΠΏΠ°ΠΌΠΈ. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ опишСм систСмныС Π²Ρ‹Π·ΠΎΠ²Ρ‹, ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‰ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ сСмафор.

5.2.1. Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈ освобоТдСниС сСмафоров

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ semget() ΠΈ semctl() Π²Ρ‹Π΄Π΅Π»ΡΡŽΡ‚ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‚ сСмафоры, функционируя ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ функциям shmget() ΠΈ shmctl(). ΠŸΠ΅Ρ€Π²Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ semget() являСтся ΠΊΠ»ΡŽΡ‡, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Π³Ρ€ΡƒΠΏΠΏΡƒ сСмафоров; Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это число сСмафоров Π² Π³Ρ€ΡƒΠΏΠΏΠ΅; Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” Ρ„Π»Π°Π³ΠΈ ΠΏΡ€Π°Π² доступа, ΠΊΠ°ΠΊ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ shmget(). Ѐункция semget() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π³Ρ€ΡƒΠΏΠΏΡ‹ сСмафоров. Если Π·Π°Π΄Π°Π½ ΠΊΠ»ΡŽΡ‡, ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠΉ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΉ Π³Ρ€ΡƒΠΏΠΏΠ΅, Π±ΡƒΠ΄Π΅Ρ‚ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ Π΅Π΅ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€. Π’ этом случаС Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ (число сСмафоров) ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ Π½ΡƒΠ»ΡŽ.

Π‘Π΅ΠΌΠ°Ρ„ΠΎΡ€Ρ‹ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡŽΡ‚ ΡΡƒΡ‰Π΅ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°ΠΆΠ΅ послС Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ всС Ρ€Π°Π±ΠΎΡ‚Π°Π²ΡˆΠΈΠ΅ с Π½ΠΈΠΌΠΈ процСссы Π·Π°Π²Π΅Ρ€ΡˆΠΈΠ»ΠΈΡΡŒ. Π§Ρ‚ΠΎΠ±Ρ‹ систСма Π½Π΅ исчСрпала Π»ΠΈΠΌΠΈΡ‚ сСмафоров, послСдний процСсс Π΄ΠΎΠ»ΠΆΠ΅Π½ явно ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Π³Ρ€ΡƒΠΏΠΏΡƒ сСмафоров. Для этого Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ semctl(), ΠΏΠ΅Ρ€Π΅Π΄Π°Π² Π΅ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π³Ρ€ΡƒΠΏΠΏΡ‹, число сСмафоров Π² Π³Ρ€ΡƒΠΏΠΏΠ΅, Ρ„Π»Π°Π³ IPC_RMID ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° union semun (ΠΎΠ½ΠΎ игнорируСтся). Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ EUID (эффСктивный ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ) процСсса, Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π°Ρ‚ΡŒ с Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ процСсса, создавшСго Π³Ρ€ΡƒΠΏΠΏΡƒ сСмафоров (Π»ΠΈΠ±ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ процСсс Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΏΡƒΡ‰Π΅Π½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ root). Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… сСгмСнтов памяти, удаляСмая Π³Ρ€ΡƒΠΏΠΏΠ° сСмафоров Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ освобоТдаСтся.

Π’ листингС 5.2 прСдставлСны Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π²Ρ‹Π΄Π΅Π»ΡΡŽΡ‰ΠΈΠ΅ ΠΈ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°ΡŽΡ‰ΠΈΠ΅ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ сСмафор.

Листинг 5.2. (sem_all_deall.c) Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈ освобоТдСниС Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ сСмафора

#include <sys/ipc.h>

#include <sys/sem.h>

#include <sys/types.h>


/* Π’ΠΈΠΏ union semun Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ. */

union semun {

 int val;

 struct semid_ds *buf;

 unsigned short int* array;

 struct seminfo *__buf;

};


/* ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ сСмафора ΠΈ создаСм сСмафор,

   Ссли ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ оказываСтся ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ. */

int binary_semaphore_allocation(key_t key, int sem_flags) {

 return semget(key, 1, sem_flags);

}


/* ОсвобоТдаСм сСмафор, подразумСвая, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ

   большС Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ с Π½ΠΈΠΌ. Π’ случаС ошибки

   возвращаСтся -1. */

int binary_semaphore_deallocate(int semid) {

 union semun ignored_argument;

 return semctl(semid, 1, IPC_RMID, ignored_argument}

}

5.2.2. Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ сСмафоров

Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΈ инициализация сСмафора β€” Π΄Π²Π΅ Ρ€Π°Π·Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ сСмафор, Π²Ρ‹Π·ΠΎΠ²ΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ semctl(), Π·Π°Π΄Π°Π² Π²Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Ρ€Π°Π²Π½Ρ‹ΠΌ Π½ΡƒΠ»ΡŽ, Π° Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” Ρ€Π°Π²Π½Ρ‹ΠΌ константС SETALL. Π§Π΅Ρ‚Π²Π΅Ρ€Ρ‚Ρ‹ΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ Ρ‚ΠΈΠΏ union semun, ΠΏΠΎΠ»Π΅ array ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° массив Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠ° unsigned short. КаТдоС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΎΠ΄ΠΈΠ½ сСмафор ΠΈΠ· Π½Π°Π±ΠΎΡ€Π°.

Π’ листингС 5.3 прСдставлСна функция, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰Π°Ρ Π΄Π²ΠΎΠΈΡ‡Π½Ρ‹ΠΉ сСмафор.

Листинг 5.3. (sem_init.c) Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ сСмафора

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>


/* Π’ΠΈΠΏ union semun Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ. "/

union semun {

 int val;

 struct semid_ds* buf;

 unsigned short int *array;

 struct seminfo *__buf;

};


/* Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ сСмафора Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ 1. */

int binary_semaphore_initialize(int semid) {

 union semun argument;

 unsigned short values(1);

 values[0] = 1;

 argument.array = values;

 return semctl(semid, 0, SETALL, argument);

}

5.2.3. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ оТидания ΠΈ установки

ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ сСмафор ΠΈΠΌΠ΅Π΅Ρ‚ Π½Π΅ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ оТидания ΠΈ установки. БистСмный Π²Ρ‹Π·ΠΎΠ² semop() Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ ΠΎΠ±Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. ΠŸΠ΅Ρ€Π²Ρ‹ΠΌ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ являСтся ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π³Ρ€ΡƒΠΏΠΏΡ‹ сСмафоров. Π’Ρ‚ΠΎΡ€ΠΎΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это массив Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Ρ‚ΠΈΠΏΠ° struct sembuf, Π·Π°Π΄Π°ΡŽΡ‰ΠΈΡ… выполняСмыС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Π’Ρ€Π΅Ρ‚ΠΈΠΉ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ β€” это Π΄Π»ΠΈΠ½Π° массива.

НиТС пСрСчислСны поля структуры sembuf.

β–  sem_num β€” Π½ΠΎΠΌΠ΅Ρ€ сСмафора Π² Π³Ρ€ΡƒΠΏΠΏΠ΅.

β–  sem_op β€” число, Π·Π°Π΄Π°ΡŽΡ‰Π΅Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ.

Если Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΠΎΠ»Π΅ содСрТит ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ число, ΠΎΠ½ΠΎ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ добавляСтся ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ сСмафора.

Если Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΠΎΠ»Π΅ содСрТит ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ число, Ρ‚ΠΎ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ числа вычитаСтся ΠΈΠ· значСния сСмафора. ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, приводящиС ΠΊ установкС ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ значСния, Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора Π½Π΅ станСт достаточно большим (вслСдствиС дСйствий Π΄Ρ€ΡƒΠ³ΠΈΡ… процСссов).

Если Π΄Π°Π½Π½ΠΎΠ΅ ΠΏΠΎΠ»Π΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ, опСрация блокируСтся Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ сСмафора Π½Π΅ станСт Ρ€Π°Π²Π½Ρ‹ΠΌ Π½ΡƒΠ»ΡŽ.

β–  sem_flg β€” это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„Π»Π°Π³Π°. Π€Π»Π°Π³ IPC_NOWAIT ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ. Если Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌΠ°Ρ опСрация ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ, функция semop() Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ Π²Ρ‹Π΄Π°Ρ‡Π΅ΠΉ ΠΊΠΎΠ΄Π° ошибки. ΠŸΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ Ρ„Π»Π°Π³Π° SEM_UNDO ОБ Linux автоматичСски ΠΎΡ‚ΠΌΠ΅Π½ΠΈΡ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π½ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ процСсса.

Π’ листингС 5.4 ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ оТидания ΠΈ установки Π΄Π²ΠΎΠΈΡ‡Π½ΠΎΠ³ΠΎ сСмафора.