繁体   English   中英

当两个进程试图访问信号量= 0的关键部分时会发生什么?

[英]What happens when two processes are trying to access a critical section with semaphore = 0?

在我的代码中,执行以下初始化:

struct PipeShm myPipe = { .init = 0 , .flag = FALSE , .mutex = NULL , .ptr1 = NULL , .ptr2 = NULL ,
        .status1 = -10 , .status2 = -10 , .semaphoreFlag = FALSE };

int initPipe()
{
    if (!myPipe.init)
    {
        myPipe.mutex = mmap (NULL, sizeof *myPipe.mutex, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0);

        if (!sem_init (myPipe.mutex, 1, 0))  // semaphore is initialized to 0
        {
            myPipe.init = TRUE;
        }
        else
            perror ("initPipe");
    }
    return 1;   // always successful
}

我可以有多个可以从main()调用的进程(请注意fork )。

谢谢

AFAICS,您的错误出在控制变量中。 进程之间仅共享mutex变量,而initflag变量不共享。 这些都是写时复制的,因此您不会在其他过程中看到更改。

您必须将所有控制变量打包到您创建的段中。 为所需的所有字段创建一个适当的struct类型。

顺便说一句,调用信号量mutex确实不是一个好主意。 互斥锁的语义与信号量完全不同。 (或者,如果您确实将其用作互斥锁,则没有检查,请在初始化器中将pthread_mutex_tpshared一起使用。)

编辑后进行编辑:不,它不会像这样工作。 您确实必须将整个struct放置在共享段中。 因此,您的struct PipeShm必须包含sem_t sem而不是sem_t* mutex 然后你会做类似的事情

struct PipeShm * myPipe = 0;

int initPipe()
{
    if (!myPipe->init)
    {
        myPipe = mmap (NULL, sizeof *myPipe, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0);

        if (!sem_init (myPipe->sem, 1, 0))  // semaphore is initialized to 0
        {
            myPipe->init = true;
        }
        else
            perror ("initPipe");
    }
    return 1;   // always successful
}

您应该注意的其他事项:

  • sem_t接口可以被任何类型的IO或其他信号中断。 您始终必须检查这些函数的返回,尤其是在收到EINTR重新启动该函数。
  • Mondern C具有布尔值。 通过在boolfalsetrue名称中包含<stdbool.h>可以轻松使用此功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM