У вас должна быть проверка ошибок в ваших вызовах семафоров. Используйте perror()
для отображения ошибки, если sem_wait()
, sem_init()
или sem_post()
возвращает ненулевое значение.
Во-вторых, вы создаете больше процессов, чем думаете. Ваш первый fork()
приводит к родителю (с producer
не ноль) и ребенку (с producer
ноль). Оба процесса затем выполняют второй fork()
, так что теперь у вас есть четыре процесса.
В-третьих, переменная sem_t
должна совместно использоваться процессами, поэтому она должна храниться в области общей памяти. Самый простой способ добиться этого с помощью mmap()
:
sem_t *sem = mmap(NULL, sizeof *sem, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
(Выполните это до sem_init()
и до первого fork()
).
В-четвертых, не определено, какой процесс будет запускаться первым, поэтому нельзя полагаться на поток производителя, вызывающий sem_wait()
, до того, как это сделает потребитель. Вместо этого инициализируйте семафор нулями с sem_init()
, и только , вызовите sem_wait()
у потребителя - это заблокирует потребителя. Производитель выполняет и вызывает sem_post()
, когда это сделано, что позволяет потребителю продолжить.
В вызове sem_init()
следует указать pshared
как ненулевое значение и value
как 0, поэтому оно должно выглядеть следующим образом:
if (sem_init(sem, 1, 0) != 0) {
perror("sem_init");
exit(1);
}
В-пятых, wait(NULL)
ожидает только одного дочернего процесса для выхода. Вызовите его дважды, чтобы дождаться двух дочерних процессов.