- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须解决两个进程之间的同步问题,并且我必须使用信号来完成它。
两个进程应该完成给定量的工作,然后向另一个进程发出信号。这将无限期地发生。
我的代码发生的情况是:
我向父进程发送信号,父进程向子进程发送信号,子进程再次向父进程发送信号,子进程被停止并且不再执行。
理想情况下, parent 和 child 应该无限期地互相发出信号。
int main () {
parent_pid = getpid();
pid_t pid = fork();
if (pid < 0) {
syserr_quit("fork error");
} else if (pid == 0) {
signal(SIGUSR2, child_work);
while (1) {}
} else {
child_pid = pid;
signal(SIGUSR1, parent_work);
while (1) {}
}
}
void child_work (int signo) {
sleep(1); // fake child work
if (kill(parent_pid, SIGUSR1) < 0) syserr_quit("kill error");
// wait for parent signal
pause();
}
void parent_work (int signo) {
sleep(1); // fake parent work
if (kill(child_pid, SIGUSR2) < 0) syserr_quit("kill error");
// wait for child signal
pause();
}
无法找出问题所在,因为代码量非常小,而且对我来说一切似乎都已就位。
如果有人想在他们的机器上启动它,这里是 a full demo复制/粘贴后即可使用。
<小时/>根据一些评论,我诉诸使用 sigaction
为了避免竞争条件并停止使用 sleep
在演示中。文档指出,为了避免在处理程序执行期间信号接收被阻止,必须设置 SA_NODEFER
标志。
代码仍然表现错误,只是这次是子进程停止接收信号。
代码片段与上面相同,但 signal
除外被交换 – 两次 – 与
struct sigaction action;
action.sa_handler = parent/child_work;
action.sa_flags = SA_NODEFER;
sigaction(signo, &action, NULL);
<小时/>
完整代码
要启动信号发送,请从控制台检查并发送信号(即 kill -SIGUSR1 <parentid>
)
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void parent_work(int signo);
void child_work(int signo);
void syserr_quit(char *msg);
pid_t parent_pid;
pid_t child_pid;
int main () {
parent_pid = getpid();
printf("parent pid: %d\n", parent_pid);
pid_t pid = fork();
if (pid < 0) {
syserr_quit("fork error");
} else if (pid == 0) {
struct sigaction action;
action.sa_handler = child_work;
action.sa_flags = SA_NODEFER;
sigaction(SIGUSR2, &action, NULL);
while (1) {}
} else {
child_pid = pid;
printf("child pid: %d\n", pid);
struct sigaction action;
action.sa_handler = parent_work;
action.sa_flags = SA_NODEFER;
sigaction(SIGUSR1, &action, NULL);
while (1) {}
}
}
void child_work (int signo) {
for (int i = 0; i < 100000000; ++i); // fake child work
// signal parent that a write is now possible
printf("send signal to %d\n", parent_pid); fflush(stdout);
if (kill(parent_pid, SIGUSR1) < 0) syserr_quit("kill error");
printf("signal sent\n"); fflush(stdout);
// wait for parent signal
pause();
}
void parent_work (int signo) {
for (int i = 0; i < 100000000; ++i); // fake child work
// signal child that a read is possible
printf("send signal to %d\n", child_pid); fflush(stdout);
if (kill(child_pid, SIGUSR2) < 0) syserr_quit("kill error");
printf("signal sent\n"); fflush(stdout);
// wait for child signal
pause();
}
void syserr_quit(char *msg) {
perror(msg);
exit(EXIT_FAILURE);
}
<小时/>
好吧,伙计们,更新的代码似乎不起作用只是因为我没有正确初始化 sigaction
面具。必须使用 sigemptyset
来完成你可以找出原因 right here .
更多详细信息请参见the answer .
最佳答案
当调用 SIGUSR1
信号处理程序 parent_work
时,SIGUSR1
信号会映射到 SIG_DFL
(默认信号处理)或忽略父进程(引用 signal
):
When a signal occurs, and func points to a function, it is implementation-defined whether the equivalent of a:
signal(sig, SIG_DFL);
is executed or the implementation prevents some implementation-defined set of signals (at least including sig) from occurring until the current signal handling has completed.
当子进程再次为父进程生成 SIGUSR1
信号时,它不会因此再次调用 parent_work
信号处理程序。
因此,在信号处理程序中,如果您希望后续信号也由信号处理程序处理,则需要再次重新注册信号:
void parent_work(int signo) {
/* your handler code */
signal(signo, parent_work);
}
请注意,这仍然为竞争条件留下了空间 - 即。如果第二个 SIGUSR1
在信号处理程序重新注册之前到达。但实际上,这是您设计的本质。
当然有更好的选择和一般建议。其中一些已经在评论中提到过,所以如果您有兴趣,我将引用这些内容。
关于c - 为什么这个进程不再处理 SIGUSR1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43981759/
我最近更新了 ADT 插件,我的整个 Eclipse-Android 构建系统都停止工作了。从那以后,我尝试了我在互联网上可以找到的所有关于如何解决这个问题的方法。徒然。如果有人有确定的方法来解决此问
我已经知道有类似的话题,但对我来说没有任何帮助...... 这里是信息: 该应用程序始终在模拟器和设备上运行。我最近将该项目重命名为另一个名称。仍然工作得很好。今天我意识到它没有更改文件夹名称,然后它
在装有El Capitan的MacMini上,我无法再进行冲泡了。我收到以下错误: /usr/local/Library/Homebrew/config.rb:34:in `initialize':
是的,所以我不知道发生了什么。我一直在编写一个 AJAX 评论脚本,并且它可以工作,但它不再工作了。我从备份中恢复了它,以防万一我改变了任何东西,但没有运气。它转到表单的“操作”而不是 jQuery,
请原谅我的无能...我正在尝试在全局 var 阶段不再未定义后使用 Proxy 执行一些代码。这是我天真的尝试: ``` var stage = undefined let myObj; let st
我对 segues 了解不多,但我已经开始工作了..但突然间它不再工作了...... 我的代码似乎可以工作,但没有发生 segue: NSLog(@"login started"); if ([use
我已将以下重写规则添加到我的 web.config 中。它运行良好,阻止了所有提及的推荐垃圾邮件站点。然而,今天我突然注意到 social-buttons.com 突然出现在我的 Google Ana
在 C++ 中,可以在翻译单元中使用 static 关键字来影响符号(变量或函数声明)的可见性。 在 n3092 中,这已被弃用: Annex D.2 [depr.static] The use of
升级到 com.crashlytics.sdk.android:crashlytics:2.7.1@aar 后(从 2.6.8 开始),我无法再在 Firebase 应用中禁用 Crashlytics
您好,我遇到了一些障碍,我一直在为我的应用程序重新设计菜单导航。我设法做到了。但现在我的应用程序的一项功能已决定停止运行。 想法是你摇动你的手机,它会随机选择一张图片,与应用程序分开的代码工作正常,就
我有一行(容器)包含三个元素,我想水平显示它们之间的间距相等(并且行的左侧或右侧没有空格)。我正在使用带有 justify-content:space-between 的 flexbox。 这是在 F
直到最近,我才能够在 Windows 上使用 python 3.6.7 时安装 tensorflow 1.5.0 包。现在我不能,从下面的“来自版本”的消息来看,似乎根本没有可用的 tensorflo
不确定是否与最近的更新有关,但我突然无法在 Android Studio 编辑器中获得单行间距。如果我尝试将它更改为 1,它让我设置它,但当我按下“应用”时,它会迅速恢复为 1.5。用不同的字体试过,
我遵循了有关如何在 macOS 上安装 pip 的在线说明(例如 this、this 和 this)。 我看起来很简单,但它不适合我。 我的 python --version 是 2.7.10。 当我
Due to rounding errors, most floating-point numbers end up being slightly imprecise. https://www.flo
我试图让用户从他们在 Android 上的库中选择一张图片。但是当我使用 PictureChooser 插件时,它似乎不再起作用了 我看到这段代码可以工作,但现在不行了,我也不知道为什么。
自 .NET 4.5 起,Exception.HResult 的 setter/getter 现在是 public,但它曾经是 protected。 来自 MSDN: Starting with th
今天去处理一个较旧的 Python2.7 AppEngine 标准项目,但我似乎无法让端点工作。我下载了示例代码,看看我的项目是否是罪魁祸首,但该示例也不起作用。 https://cloud.goog
我是一名优秀的程序员,十分优秀!