简体   繁体   English

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

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

In my code I do the following initialization : 在我的代码中,执行以下初始化:

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
}

I can have multiple processes that can be invoked from main() (note the fork ) . 我可以有多个可以从main()调用的进程(请注意fork )。

Thanks 谢谢

AFAICS your error is in your control variables. AFAICS,您的错误出在控制变量中。 Only your mutex variable is shared between the processes, not your init or flag variables. 进程之间仅共享mutex变量,而initflag变量不共享。 These are copy on write, so you wouldn't see the changes in a different process. 这些都是写时复制的,因此您不会在其他过程中看到更改。

You'd have to pack all of your control variables inside the segment that you create. 您必须将所有控制变量打包到您创建的段中。 Create an appropriate struct type for all the fields that you need. 为所需的所有字段创建一个适当的struct类型。

BTW, calling a semaphore mutex is really a bad idea. 顺便说一句,调用信号量mutex确实不是一个好主意。 A mutex has a semantic that is quite different from a semaphore. 互斥锁的语义与信号量完全不同。 (Or if you really use it as a mutex, I didn't check, use pthread_mutex_t with pshared in the initializer.) (或者,如果您确实将其用作互斥锁,则没有检查,请在初始化器中将pthread_mutex_tpshared一起使用。)

Edit after your edit: No it wouldn't work like this. 编辑后进行编辑:不,它不会像这样工作。 You really have to place the whole struct in the shared segment. 您确实必须将整个struct放置在共享段中。 So your struct PipeShm must contain a sem_t sem and not a sem_t* mutex . 因此,您的struct PipeShm必须包含sem_t sem而不是sem_t* mutex Then you'd do something like 然后你会做类似的事情

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
}

Other things you should be aware of: 您应该注意的其他事项:

  • The sem_t interfaces can be interrupted by any kind of IO or other signals. sem_t接口可以被任何类型的IO或其他信号中断。 You always have to check the return of these functions and in particular restart the function if it received EINTR . 您始终必须检查这些函数的返回,尤其是在收到EINTR重新启动该函数。
  • Mondern C has a Boolean. Mondern C具有布尔值。 This you can easily use by including <stdbool.h> through names of bool , false and true . 通过在boolfalsetrue名称中包含<stdbool.h>可以轻松使用此功能。

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

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