Ожидание 0 для именованного Posix семафора
Что бы было, например, так:
sem_wait_null(...); //программа блокируется
Или в Linux можна даную задачу реализовать другим способом?
Уменьшение на единицу не подходит.
Есть семафоры и для процессов
Именованные семафоры, о которых я спрашивал - и есть "глобальные" семафоры. Т.е. для процесов.
(аналогичные семафорам System V) - смотри semget и semctl (sys/sem.h). Это аналоги тех же функций, что и в System V.
В хидере sys/sem.h объявлены семафоры System V. Это не аналоги. Семафоры Posix - semaphore.h.
Глобальные семафоры могут быть как именнованные, так и безымянные. Тот же вызов sem_init для неименованных семафоров, имеет поле pshared, которое определяет его "глобальность". Для именованых sem_open.
Вы правы, именно они, кстати я это упомянул. Но это линух? Линух. Вы же сами спрашивали
Ну вот. Можно. Используете теже семафоры System V. Линух их поддерживает.
Не все так просто. Поле pshared недостаточно для "разшаривания". Нужно плюс его еще разместить в IPC Shared memory.
Вы правы, именно они, кстати я это упомянул. Но это линух? Линух. Вы же сами спрашивали
Ну вот. Можно. Используете теже семафоры System V. Линух их поддерживает.
Уже используються. Но в связи с тем, что семафоры Posix намного "легковеснее" и проще в работе нежели System V - есть идея перейти на Posix.
Сейчас просто есть свои реализации паттерна Consumer/Producer, и в одной из реализаций используеться ожидание значения 0 семафора.
Так а чем sem_wait -то неподходит?
При вызове sem_wait поток блокируется до того момента, пока значение семафора не станет положительным. Нужно наоборот, что бы при вызове функции поток блокировался пока значения семафора не станет нулевым. Для семафоров SystemV это делаеться просто:
int wait_null(int semid)
{
struct sembuf operations[1];
operations[0].sem_num = 0;
operations[0].sem_op = 0;
operations[0].sem_flg = 0/*SEM_UNDO*/;
return semop(semid,operations,1);
}
Но для Posix семафоров решения я не знаю.
Что нибудь типа:
while(condition_is_false)
pthread_cond_wait();
pthread_mutex_unlock();