我正在尝试设计5个生产者和单个消费者模型。我刚刚学会了如何从维基百科Producer-consumer problem设计模型。但我很难避免死锁。我不明白为什么这段代码导致死锁。
这是消费者。 (假设单个进程执行此代码。所有信号量和共享内存都已初始化。)
int main()
{
Shared_Data = (shared_data*)Shared_Address; // this is a shared memory.
for(i = 0 ; i < 5; i++)
{
sprintf(debugbuf, "%ld, filled downsem, %dth loop\n", (long)getpid(), i);
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_wait(filled); // try to access to the shared memory.
// if the shared memory is empty, consumer waits for it to be filled with pid and state.
read.isIdle = I_AM_IDLE;
read.WrittenByPid = Shared_Data->WrittenByPid;
sprintf(debugbuf, "%ld, empty upsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_post(empty);
}
}
这是制片人。 (假设有五个进程执行此代码,并且所有信号量和共享内存都已初始化。)
int main()
{
sprintf(debugbuf, "%ld, empty downsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
// only one child process have access to here.
sem_wait(empty); // another child process doen't have access to here,
// untill parent process reads the shared memory.
sprintf(writebuf, "%s %ld process is forked.\n", Get_CurrentTime(date), (long)getpid());
write(STDOUT_FILENO, writebuf, strlen(writebuf));
Put_itsState_into_SharedMemory(getpid(), I_AM_IDLE, YES_Virgin);
sprintf(debugbuf, "%ld, filled upsem\n", (long)getpid());
write(STDOUT_FILENO, debugbuf, strlen(debugbuf));
sem_post(filled);
}
但我有以下结果。
32685, filled downsem, 0th loop
32687, empty downsem
32687, filled upsem
32685, empty upsem
32685, filled downsem, 1th loop
32690, empty downsem
32689, empty downsem
32691, empty downsem
32688, empty downsem
[stuck in for-loop]
任何帮助都会很棒。谢谢。
答案 0 :(得分:2)
您应该始终检查sem_wait
的返回值是什么。
如果您在sem_wait
函数中并且有中断,则sem_wait
将返回不等于0的错误。
然后,您需要使用errno
检查是否发生了中断。
由于您使用fork
,因此当一个子进程退出时,您可以获得SIGCHLD
中断。