【问题标题】:What happens when two processes are trying to access a critical section with semaphore = 0?当两个进程试图访问信号量 = 0 的临界区时会发生什么?
【发布时间】:2012-07-27 07:50:58
【问题描述】:

在我的代码中,我做了以下初始化:

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)。

谢谢

【问题讨论】:

  • 您调用fork() 两次:一次在开始时,一次在 if 条件内
  • @knittl:好的,那有什么问题?这是故意的
  • 你最终有 4 个进程(父子进程都再次 fork())。第二个 fork (if(fork())) 的进程将分别拥有原始信号量的不同副本。
  • @knittl:if 中的fork 负责输出,每次输出 1 个。如果我在那之前添加一个叉子,那么我应该期待2 输出......或者不是? .... 是的,我知道他们会有 2 个副本,但即便如此,有时我只会得到 1 输出。!为什么?
  • 可能是竞争条件。未指定 fork 后的执行顺序。调用 fork 后任何地方都可能发生上下文切换,你永远不知道是先执行 child 还是 parent。

标签: c linux shared-memory semaphore


【解决方案1】:

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 有一个布尔值。您可以通过包括 <stdbool.h> 通过boolfalsetrue 的名称。

【讨论】:

  • 我已经这样做了,它仍然在继续。请参阅编辑后的帖子以及对 struct 的修改。我在 H 文件中有结构,我在 C 文件中初始化它
  • 但是我在代码中使用了sem_wait(),它的原型是int sem_wait(sem_t *sem);,例如它获取一个指针作为参数...
  • 我放了一个&,它就可以编译了。然而问题仍然存在,即使我做了你写的确切修改。这有点奇怪,伙计:)
猜你喜欢
  • 1970-01-01
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-05
相关资源
最近更新 更多