0

我正在尝试设计 5 个生产者和单一消费者模型。我刚刚从Producer-consumer problem,Wikipedia 中学习了如何设计模型。但是我很难避免死锁。我不明白为什么这段代码会导致死锁。

这里是消费者。(假设单个进程执行此代码。并且所有信号量和共享内存都已初始化。)

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]

任何帮助都是极好的。谢谢你。

4

1 回答 1

2

你应该经常检查,返回值sem_wait是什么。

如果你在sem_wait函数中并且有中断进来,那么sem_wait将返回一个不等于0的错误。然后你需要检查是否发生了中断,用errno.

由于您使用fork您可以在一个子进程退出时获得SIGCHLD中断。

于 2013-05-30T11:31:33.103 回答