[英]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 上运行。你有三个问题。
首先是您正在尝试同步两个进程。 当您在两个进程之间共享信号量时,根据手册页,您需要
你的第二个问题是父母和孩子都在等待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.