gpt4 book ai didi

c - 使用信号量同步进程

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:07:42 25 4
gpt4 key购买 nike

我很难理解如何使用信号量在两个进程之间交替控制。这是流程处理代码的人为示例。

int pid = fork();

if (pid) {
int counter = 0;
while (true) {
counter += 1;
printf("P%d = %d", pid, counter);
}
} else {
int counter = 0;
while (true) {
counter += 1;
printf("P%d = %d", pid, counter);
}
}

我原以为上面的代码会并行运行,但对于 fork 进程,控制流似乎会立即继续,然后才为父进程恢复。

这从根本上打破了我现有的代码,该代码使用信号量来控制哪个进程可以执行操作。

int id = get_semaphore(1);
int pid = fork();

if (pid) {
int counter = 0;
while (true) {
sem_wait(id);
counter += 1;
printf("P%d = %d\n", pid, counter);
sem_signal(id);
}
} else {
int counter = 0;
while (true) {
sem_wait(id);
counter += 1;
printf("P%d = %d\n", pid, counter);
sem_signal(id);
}
}
  • sem_wait 助手只是从信号量值中减去 1 并阻塞直到结果 > 0(在后台使用 semop)。

  • sem_signal 助手只是将信号量值加 1(在后台使用 semop)。

我希望代码在两个进程之间交替,使用 sem_wait 阻塞,直到另一个进程使用 sem_signal 释放资源。所需的输出将是:

P1 = 0
P0 = 0
P1 = 1
P0 = 1
...

然而,由于进程之间的初始执行延迟,子进程获取可用的信号量资源,用它来打印一个数字,然后恢复它并循环——此时资源再次可用,所以它继续没有一直在等待其他进程。

如果进程自行释放资源,防止进程使用资源的最佳方法是什么?

最佳答案

it seems like control flow continues instantly for the forked process and only later resumes for the parent process

那是因为流 IO 缓冲 stdout 上的输出,直到

  • 缓冲区已满
  • fflush()stdout
  • 上调用
  • 遇到换行符(\n)

在您的程序中,每个进程在将其内容发送到 stdout 之前会填充一个缓冲区,从而给出一个进程运行很长时间的外观,然后是另一个进程。用 \n 终止 printf 语句的格式字符串,您会在第一个程序中看到更符合您预期的行为。

我不确定为什么你的信号量不起作用——我对系统 V 信号量不是很了解,但对我来说,你在 fork 后得到信号量似乎是一个危险信号。对于更常见的 POSIX 信号量,信号量必须位于两个进程都可以看到的内存中,否则它就是两个信号量。

无论如何,假设您的 get_semaphore() 函数做了正确的事情来共享信号量,仍然存在一个问题,因为不能保证当一个进程发出信号量时,另一个进程会尽快开始,以便它在第一个进程循环并自己捕获它之前再次捕获它。

您需要两个信号量,一个给父级,一个给子级。在打印之前,每个进程都应该等待自己的信号量。打印后,每个进程都应向另一个信号量发出信号。此外,一个信号量应初始化为 1,另一个应初始化为 0。

关于c - 使用信号量同步进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43278608/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com