Однако я столкнулся с загадкой на всю жизнь, если официант уничтожает семафор сразу после того, как он возвращается из режима ожидания. Использование интерфейса POSIX для демонстрационных целей:
Код: Выделить всё
#include
#include
void* thread_fun(void* arg)
{
sem_t* sem = (sem_t*)arg;
sem_post(sem);
return NULL;
}
int main()
{
sem_t sem;
sem_init(&sem, 0, 0); // initial value == 0
pthread_t thread;
pthread_create(&thread, NULL, thread_fun, &sem);
sem_wait(&sem);
sem_destroy(&sem);
pthread_join(thread, NULL);
}
Код: Выделить всё
void sem_post(sem_t* sem)
{
atomic_fetch_add(&sem->data, +1); // A
futex_wake(&sem->data); // B
}
void sem_wait(sem_t* sem)
{
int32_t previous = atomic_fetch_add(&sem->data, -1); // C
while(previous data, previous);
previous = atomic_load(&sem->data);
if(previous > 0 && atomic_compare_exchange_weak(&sem->data, &previous, expected + 1))
break;
}
}
- постер выполняет A (atomic_fetch_add +1)
- официант выполняет C (atomic_fetch_add -1)
- официант возвращается и уничтожает семафор
- постер выполняет B (futex_wake )
Как это реализуется на практике?
Подробнее здесь: https://stackoverflow.com/questions/785 ... sing-futex
Мобильная версия