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

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«QNX/UNIX: Анатомия ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΠΈΠ·ΠΌΠ°Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 37

Автор ОлСг Π¦ΠΈΠ»ΡŽΡ€ΠΈΠΊ

Для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ° сСмафоров сущСствуСт своя Π³Ρ€ΡƒΠΏΠΏΠ° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΠΌΠ΅ΡˆΠΈΠ²Π°Ρ‚ΡŒΡΡ.

sem_init() ΠΈ sem_destroy() β€” созданиС ΠΈ Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ сСмафора. ΠŸΡ€ΠΈ создании указываСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ доступа ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика сСмафора. Π‘ Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ сСмафором Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ нСльзя (это ΠΎΠ±Ρ‰Π΅Π΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ справСдливо ΠΈ для всСх ΠΈΠ½Ρ‹Ρ… ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΎΠ² синхронизации). ПослС Ρ€Π°Π·Ρ€ΡƒΡˆΠ΅Π½ΠΈΡ сСмафора Π΅Π³ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ для использования.

ОбС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ 0 Π² случаС успСха ΠΈ -1 Π² случаС ошибки. Код ошибки записываСтся Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ errno. Π’ частности, функция sem_init() ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΈΠ³Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… выполнСния:

EAGAIN β€” Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π½Π΅Ρ‚ рСсурсов для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ сСмафора;

EINVAL β€” Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ°Π΅Ρ‚ SEM_VALUE_MAX;

EPERM β€” Ρƒ процСсса нСдостаточно ΠΏΡ€ΠΈΠ²ΠΈΠ»Π΅Π³ΠΈΠΉ для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ сСмафора;

ENOSPC β€” рСсурсы, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΡ‹Π΅ для ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, исчСрпаны;

ENOSYS β€” функция sem_init() Π½Π΅ поддСрТиваСтся Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ систСмы.

ΠŸΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ sem_destroy() ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½Π° ошибка:

EINVAL β€” Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΎΠΏΠΈΡΠ°Ρ‚Π΅Π»ΡŒ сСмафора.

sem_open() ΠΈ sem_close() β€” ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΈ Π·Π°ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ сСмафора (Ссли отсутствуСт Ρ€Π°Π½Π΅Π΅ созданный сСмафор с Ρ‚Π°ΠΊΠΈΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ, Ρ‚ΠΎ Π΅Π³ΠΎ созданиС). Π’ вопросС ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΈ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ Ρ€Π°Π±ΠΎΡ‚Π° с ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ сСмафором Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½Π° Ρ€Π°Π±ΠΎΡ‚Π΅ с ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠΌ. Π’Π°ΠΊΠΆΠ΅ для ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… сСмафоров сущСствуСт опСрация sem_unlink(), аналогичная ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ unlink() для ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π°. Π’ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sem_open() пСрСдаСтся имя сСмафора, ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ открытия сСмафора ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Π² случаС создания сСмафора.

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ

Для сСмафора ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Ρ‚Ρ€ΠΈ ΠΌΠΎΠ΄ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ:

int sem_wait(sem_t* sem);

int sem_trywait(sem_t* sem);

#include <time.h>

int sem_timedwait(sem_t* sem, const struct timespec * abs_timeout);

ВсС эти Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΎΠΏΠΈΡ€Π°ΡŽΡ‚ΡΡ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ (native QNX API):

int SyncSemWait(sync_t* sync, int try);

Ѐункция простого оТидания sem_wait() пытаСтся Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика сСмафора. Если исходноС Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±Ρ‹Π»ΠΎ большС ΠΈΠ»ΠΈ Ρ€Π°Π²Π½ΠΎ 1, Ρ‚ΠΎ функция послС выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚Π° Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π² Π²Ρ‹Π·Π²Π°Π²ΡˆΠΈΠΉ ΠΊΠΎΠ΄. Если ΠΆΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ счСтчика сСмафора Ρ€Π°Π²Π½ΡΠ»ΠΎΡΡŒ 0, Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠ° блокируСтся Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика сСмафора. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΎ, Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ (Π² порядкС ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ), выполняСт (Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚) Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика сСмафора ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ состояниС ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½Π½ΠΎΠ³ΠΎ Π΅ΠΌΡƒ сигнала (см. Π³Π»Π°Π²Ρƒ 3).

Ѐункция оТидания с ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΎΠΉ сСмафора, sem_trywait(), Π΄ΠΎ выполнСния ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π°Π΄ сСмафором провСряСт Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика. Если это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ большС нуля, функция выполняСт Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ счСтчика, Π° Ссли Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ - Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΡƒ, Π½Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡΡΡŒ Π½Π° ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ доступности сСмафора (Π½ΠΎ Π·Π°Ρ…Π²Π°Ρ‚ сСмафора Π² этом случаС Π½Π΅ происходит, ΠΎ Ρ‡Π΅ΠΌ ΠΈΠ·Π²Π΅Ρ‰Π°Π΅Ρ‚ ΠΊΠΎΠ΄ Π²ΠΎΠ·Π²Ρ€Π°Ρ‚Π°).

Ѐункция оТидания с Ρ‚Π°ΠΉΠΌ-Π°ΡƒΡ‚ΠΎΠΌ, sem_timedwait(), ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ возмоТности ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Π½Π° 1 счСтчик сСмафора (блокируСтся Π½Π° ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ) Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ abs_timeout. Π­Ρ‚ΠΎ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ TimerTimeout() (native QNX API) с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ SIGEV_UNBLOCK. Благодаря этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΏΡ€Π΅Ρ€Π²Π°Π½ ряд состояний Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² (Π² Ρ‚ΠΎΠΌ числС Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π° сСмафорС, ΠΌΡŒΡŽΡ‚Π΅ΠΊΡΠ΅ ΠΈ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ).

ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ освобоТдСния

int sem_post(sem_t* sem);

Π­Ρ‚Π° опСрация ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ (ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚) Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ счСтчик сСмафора, ΠΈ Π² этом ΠΎΠ½Π° Π΄ΠΈΠ°ΠΌΠ΅Ρ‚Ρ€Π°Π»ΡŒΠ½ΠΎ ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½Π° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Если ΠΏΠ΅Ρ€Π΅Π΄ этим Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика сСмафора Π±Ρ‹Π»ΠΎ Ρ€Π°Π²Π½ΠΎ 0, Ρ‚ΠΎ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… разблокирования сСмафора, ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² состояниС готовности. Из списка ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² систСма Π²Ρ‹Π±ΠΈΡ€Π°Π΅Ρ‚ самый ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Ρ‹ΠΉ, Π° Ссли Ρ‚Π°ΠΊΠΈΡ… нСсколько, Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ, дольшС всСх Тдавший ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ².

Π­Ρ‚Π° функция ΠΈΠΌΠ΅Π΅Ρ‚ свой ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π» Π² native API QNX:

int SyncSemPost(sync_t* sync);

ЀактичСски Ρ€Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ POSIX ΠΈ QNX API Π² Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°Ρ… этой Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ состоит Π² рСгистрируСмых Сю ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ….

Ѐункция sem_post() сообщаСт ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…:

EINVAL β€” Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ дСскриптор сСмафора sem;

ENOSYS β€” функция sem_post() Π½Π΅ поддСрТиваСтся систСмой.

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ sem_post(), функция SyncSemPost() ΠΌΠΎΠΆΠ΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° ошибки:

EAGAIN β€” нСдостаточно памяти для создания Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° синхронизации;

EFAULT β€” Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° сСмафор sync;

EINTR β€” Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€Π΅Ρ€Π²Π°Π½ΠΎ сигналом;

EINVAL β€” Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ sync Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ сСмафор.

Как Π²ΠΈΠ΄ΠΈΠΌ, функция QNX API нСсколько Ρ€Π°Π·Π½ΠΎΠΎΠ±Ρ€Π°Π·Π½Π΅Π΅ Π² ΠΏΠ»Π°Π½Π΅ контроля ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° выполнСния Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ.

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ статуса сСмафора

int sem_getvalue(sem_t* sem, int* value);

Π­Ρ‚Π° функция ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ прСимущСствСнно для ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Π½Π°Π΄ сСмафорами. По адрСсу, ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ Π² value, устанавливаСтся Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика сСмафора. ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика сСмафора ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒΡΡ Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚, Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ эта функция, ΠΈΠΌΠ΅Π΅Ρ‚ смысл Ρ‚ΠΎΠ»ΡŒΠΊΠΎ нСпосрСдствСнно Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ Π΅Π΅ Π²Ρ‹Π·ΠΎΠ²Π°.

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ошибки:

EINVAL β€” Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ сСмафор sem.

ИспользованиС сСмафора

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

ΠŸΡ€ΠΎΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ всС Π²Ρ‹ΡˆΠ΅ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π½Π° Π΄Π²ΡƒΡ… ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°Ρ…. Π‘Π½Π°Ρ‡Π°Π»Π° ΠΌΡ‹ построим Β«ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ сообщСний», ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π½ΡƒΡŽ для трансляции сообщСний графичСской систСмы ΠΊ Β«ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠΌΡƒΒ» ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ Ρ€Π΅Π°ΠΊΡ†ΠΈΠΉ. Π­Ρ‚ΠΎ ΠΎΠ΄Π½ΠΎ ΠΈΠ· Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ вСсьма распространСнной Π·Π°Π΄Π°Ρ‡ΠΈ ΠΎ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠΈ «зависания» ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ интСрфСйса Π½Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄ выполнСния ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°. Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ события ΠΎΠΊΠΎΠ½Π½ΠΎΠΉ систСмы (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ ΠΈΠ»ΠΈ Π²Ρ‹Π±ΠΎΡ€Π° ΠΏΡƒΠ½ΠΊΡ‚Π° мСню) ΠΈ функция, которая нСпосрСдствСнно ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΡ‹Π΅ дСйствия (прСдусмотрСнныС ΠΏΠΎ Π½Π°ΡΡ‚ΡƒΠΏΠ»Π΅Π½ΠΈΡŽ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ события - наТатия ΠΊΠ½ΠΎΠΏΠΊΠΈ), Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Ρ‚ΡŒΡΡ Π² Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ….

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

class event {

 /* класс ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‰Π΅Π³ΠΎ события, Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰Π΅Π³ΠΎ

    ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ Π½ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта Π² Π±ΡƒΡ„Π΅Ρ€ */

public:

 event() { sem_init(&_block, 0, 0); }

 ~event() { sem_destroy(&_block); }

 void wait() { sem_wait(&_block); }

 void reset() { sem_post(&_block); }

private:

 sem_t _block;

};


/* ΡˆΠ°Π±Π»ΠΎΠ½Π½Ρ‹ΠΉ класс ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… */

template <class T> class CDataQueue {

public:

 CDataQueue() {}

 ~CDataQueue() {}

 void push(T _new_data) {

  _data_queue.push(_new_data);

  data_event.reset();

 }

 T pop() {

  data_event.wait();

  T res = _data_queue.front();

  _data_queue.pop();

  return res;

 }

private:

 std::queue<T> _data_queue;

 event data_event;

};

ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ€Π°Π±ΠΎΡ‚Ρ‹ CDataQueue Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ для хранСния вновь ΠΏΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ практичСски нСзависимыми ΠΏΠΎΡ‚ΠΎΠΊΠΈ производитСля ΠΈ потрСбитСля. НСзависимыми Π²ΠΎ всСх случаях, ΠΊΡ€ΠΎΠΌΠ΅ пустой ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ. ΠŸΠΎΡ‚Ρ€Π΅Π±ΠΈΡ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½ Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅Ρ‚ Π΄Π°Π½Π½Ρ‹Ρ… ΠΎΡ‚ производитСля. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒ внСсСт Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, ΠΏΠΎΡ‚ΠΎΠΊ потрСбитСля разблокируСтся ΠΈ считаСт эти Π΄Π°Π½Π½Ρ‹Π΅. Π’ΠΎΠ½ΠΊΠΎΡΡ‚ΡŒ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ потрСбитСля блокируСтся сам ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ pop(), Π° разблокируСтся ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠ° производитСля ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ ΠΈΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ push().