繁体   English   中英

如何使用信号量同步两个进程,以便我可以在 C 中获得所需的 output?

[英]How to use semaphores to synchronize two processes so I can have the desired output in C?

我有两个进程(一个父进程和一个子进程——我是用 fork 做的)。

在此处输入图像描述

我想使用信号量同步这两个进程,这样 output 就是“a=20”。

这是我的代码:

#include <stdio.h>
#include <semaphore.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>

sem_t sem1;
sem_t sem2;
int a=0;

int main() {
    sem_init(&sem1, 0, 1);
    sem_init(&sem2, 0, 1);

    pid_t pid = fork();

    if (pid == 0) {
        sem_wait(&sem1);
        a = 10;
       if (a == 10) {
            printf("a = %d\n", a);
       }
       sem_post(&sem2);
    } else {
        sem_wait(&sem1);
        a = 20;
        if (a == 20) {
            printf("a = %d\n", a);
        }
       sem_post(&sem2);
        wait(NULL);
    }

    sem_destroy(&sem1);
    sem_destroy(&sem2);

    return 0;
}

我希望该代码的结果始终为“a=20”,但是当我运行它时,我得到的结果是“a=20 a=10”。

首先子进程给'a'赋值10。然后父进程将'a'的值覆盖为20。然后我们进入父进程的'if'语句,检查是否a=20并打印它。 然后子进程检查 a=10 但 'a' 是否不等于 10,因为父进程给 'a' 的值为 20,但仍然打印出“a=10”,我不明白为什么。

问题是我希望孩子检查 a=10 是否留在那里但不要在屏幕上打印 a=10 的部分。 我希望 output 只是 a=20。

我假设这是在 Linux 上运行。你有三个问题。

首先是您正在尝试同步两个进程。 当您在两个进程之间共享信号量时,根据手册页,您需要

  • 第二个参数必须是非零
  • 信号量必须位于共享 memory。普通全局 memory 不共享。

你的第二个问题是父母和孩子都在等待sem1然后发布到sem2 这意味着其中一个线程可能会永远阻塞(根据手册页,如果调用它时有进程在等待,sem_destroy 会导致未定义的行为),但您无法分辨是哪一个。 你需要做的是确保子进程达到a = 10; 第一,但比较第二。 您需要在分配和比较之间进行一些同步。

您的第三个问题是每个进程都有自己a . 这个,就像信号量需要把go变成共享的memory。


要扩展同步点,您需要这样的东西(使用伪代码):

Parent
------

initialise shared memory
initialise sem1 and sem2 and a all to 0
fork

wait on sem1
set a = 20
if a == 20 print
post on sem2

Child
-----
set a = 10
post on sem1
wait on sem2
if a == 10 print

sem1 用于表示子级已将 a 设置为 10。sem2 用于表示父级已将 a 设置为 20 并打印。

根据您的体系结构和硬件,您可能必须a volatile以禁用将其保留在寄存器中的优化,并具有 memory 屏障以确保它从 CPU 缓存刷新到主 memory。

暂无
暂无

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

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