- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们的任务是开发一个创建子进程的应用程序。然后父进程等待3秒(我们不允许在父进程中使用sleep
)并发送一个SIGUSR2
信号后跟 SIGUSR1
信号。之后, parent 发送 SIGUSR1
定期(3 秒)向 child 发出信号,直到它终止。 child 终止后,它会打印 Parent done
并退出。我们应该使用 alarm()
来实现这个行为和 pause()
.
子进程应该阻塞信号 SIGUSR2
持续 13 秒。收到后SIGUSR1
它应该打印 Received SIGUSR1
.收到后SIGUSR2
它打印 Child done
并退出。我的实现方法如下:
请注意:SIGUSR2
信号只发送一次,直到现在我还没有实现它并且每次都与 SIGUSR1
一起发送信号。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <stdarg.h>
static pid_t chld;
void init_signal(struct sigaction* action, void (*handler)(int));
void init_sigset(sigset_t* set, int signum);
void bind_signal(struct sigaction* action, int n, ...);
void par_signal(int signum);
void chld_signal(int signum);
int main(){
chld = fork();
struct sigaction action;
if (chld == -1){
fprintf(stderr, "Failed to create child process.\n");
return EXIT_FAILURE;
} else if (chld == 0){
init_signal(&action, &chld_signal);
bind_signal(&action, 3, SIGUSR1, SIGUSR2, SIGALRM);
sigset_t sig;
init_sigset(&sig, SIGUSR2);
sigprocmask(SIG_BLOCK, &sig, NULL);
alarm(13);
pause();
}
init_signal(&action, &par_signal);
bind_signal(&action, 2, SIGALRM, SIGCHLD);
alarm(3);
pause();
}
void init_signal(struct sigaction* action, void (*handler)(int)){
action->sa_flags = 0;
action->sa_handler = handler;
sigemptyset(&action->sa_mask);
}
void init_sigset(sigset_t* set, int signum){
sigemptyset(set);
sigaddset(set, signum);
}
void bind_signal(struct sigaction* action, int n, ...){
va_list args;
va_start(args, n);
for (int i = 0; i < n; i++){
int signum = va_arg(args, int);
sigaction(signum, action, NULL);
}
va_end(args);
}
void par_signal(int signum){
if (signum == SIGALRM){
kill(chld, SIGUSR2);
kill(chld, SIGUSR1);
alarm(3);
pause();
} else if (signum == SIGCHLD){
printf("Parent done\n");
exit(EXIT_SUCCESS);
}
}
void chld_signal(int signum){
if (signum == SIGALRM){
sigset_t sig;
init_sigset(&sig, SIGUSR2);
sigprocmask(SIG_UNBLOCK, &sig, NULL);
pause();
} else if (signum == SIGUSR1){
printf("Received SIGUSR1\n");
pause();
} else if (signum == SIGUSR2){
printf("Child done\n");
exit(EXIT_SUCCESS);
}
}
它的工作原理与事实不同,即只有父进程的第一个信号被子进程接收到。我认为这与我对 pause
的使用有关分别alarm
.你知道我做错了什么吗?
可以找到练习任务表的链接 here (任务 3)。
最佳答案
在信号处理程序中调用 pause
是有问题的,因为在这种情况下,刚刚触发信号处理程序的信号会被阻塞,直到您从信号处理程序返回。这意味着该进程将不再对该信号使用react。信号处理程序只能由其他信号触发。
请参阅下面的系统调用跟踪和解释。为了清楚起见,我用 @PARENT@
替换了父级的 PID,用 #CHILD##
替换了子级的 PID。
$ strace -f -r -e trace=signal,process ./proc
0.000000 execve("./proc", ["./proc"], 0x7ffc146ba360 /* 74 vars */) = 0
0.001428 arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd3c958fc0) = -1 EINVAL (Invalid argument)
0.002302 arch_prctl(ARCH_SET_FS, 0x7f264e40a540) = 0
# clone is fork()
0.001086 clone(strace: Process #CHILD## attached
child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f264e40a810) = #CHILD##
# parent establishes SIGALRM handler
[pid @PARENT@] 0.000791 rt_sigaction(SIGALRM, {sa_handler=0x564709a5859c, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f264e25e470}, <unfinished ...>
# child establishes SIGUSR1 handler
[pid #CHILD##] 0.000087 rt_sigaction(SIGUSR1, {sa_handler=0x564709a58605, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f264e25e470}, <unfinished ...>
[pid @PARENT@] 0.000132 <... rt_sigaction resumed> NULL, 8) = 0
[pid #CHILD##] 0.000056 <... rt_sigaction resumed> NULL, 8) = 0
# child establishes SIGUSR2 handler
[pid #CHILD##] 0.000072 rt_sigaction(SIGUSR2, {sa_handler=0x564709a58605, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f264e25e470}, NULL, 8) = 0
# child establishes SIGALRM handler
[pid #CHILD##] 0.000141 rt_sigaction(SIGALRM, {sa_handler=0x564709a58605, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f264e25e470}, NULL, 8) = 0
# parent establishes SIGCHLD handler
[pid @PARENT@] 0.000389 rt_sigaction(SIGCHLD, {sa_handler=0x564709a5859c, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f264e25e470}, <unfinished ...>
# child blocks SIGUSR2
[pid #CHILD##] 0.000132 rt_sigprocmask(SIG_BLOCK, [USR2], NULL, 8) = 0
# child waits for signal
[pid #CHILD##] 0.000204 pause( <unfinished ...>
[pid @PARENT@] 0.000837 <... rt_sigaction resumed> NULL, 8) = 0
# parent waits for signal
[pid @PARENT@] 0.000133 pause() = ? ERESTARTNOHAND (To be restarted if no handler)
# parent receives SIGALRM
[pid @PARENT@] 3.000317 --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
# parent sends SIGUSR2 and SIGUSR1 to child
[pid @PARENT@] 0.000106 kill(#CHILD##, SIGUSR2) = 0
[pid @PARENT@] 0.000116 kill(#CHILD##, SIGUSR1) = 0
[pid #CHILD##] 0.000144 <... pause resumed> ) = ? ERESTARTNOHAND (To be restarted if no handler)
# child receives SIGUSR1 (SIGUSR2 is blocked)
[pid #CHILD##] 0.000166 --- SIGUSR1 {si_signo=SIGUSR1, si_code=SI_USER, si_pid=@PARENT@, si_uid=1000} ---
# parent waits for signal again. As this "pause" was called from a signal handler triggered by SIGALRM, this signal is now blocked.
[pid @PARENT@] 0.000227 pause( <unfinished ...>
# child waits for signal. As this "pause" was called from a signal handler triggered by SIGUSR1, this signal is now blocked.
[pid #CHILD##] 0.000566 pause() = ? ERESTARTNOHAND (To be restarted if no handler)
# child receives SIGALRM
[pid #CHILD##] 9.997742 --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
# child unblocks SIGUSR2
[pid #CHILD##] 0.000102 rt_sigprocmask(SIG_UNBLOCK, [USR2], NULL, 8) = 0
# child now receives SIGUSR2 which was already sent by the parent
[pid #CHILD##] 0.000122 --- SIGUSR2 {si_signo=SIGUSR2, si_code=SI_USER, si_pid=@PARENT@, si_uid=1000} ---
# child exits
[pid #CHILD##] 0.000183 exit_group(0) = ?
[pid #CHILD##] 0.000204 +++ exited with 0 +++
0.000081 <... pause resumed> ) = ? ERESTARTNOHAND (To be restarted if no handler)
# parent receives SIGCHLD from child
0.000056 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=#CHILD##, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
Parent done
# parent exits
0.000563 exit_group(0) = ?
0.000301 +++ exited with 0 +++
我建议从信号处理程序中设置标志,并在主函数中进行决策和等待。像这样
static volatile sig_atomic_t childSigUsr1 = 0;
static volatile sig_atomic_t childSigUsr2 = 0;
static volatile sig_atomic_t childSigAlrm = 0;
void chld_signal(int signum) {
if (signum == SIGALRM) {
childSigAlrm = 1;
} else if (signum == SIGUSR1) {
childSigUsr1 = 1;
} else if (signum == SIGUSR2) {
childSigUsr2 = 1;
}
}
int main() {
chld = fork();
struct sigaction action;
if (chld == -1) {
fprintf(stderr, "Failed to create child process.\n");
return EXIT_FAILURE;
} else if (chld == 0) {
init_signal(&action, &chld_signal);
bind_signal(&action, 3, SIGUSR1, SIGUSR2, SIGALRM);
sigset_t sig;
init_sigset(&sig, SIGUSR2);
sigprocmask(SIG_BLOCK, &sig, NULL);
alarm(13);
while(1) {
pause();
if(childSigUsr1) {
childSigUsr1 = 0;
printf("Received SIGUSR1\n");
}
if(childSigUsr2) {
childSigUsr2 = 0;
printf("Child done\n");
exit(EXIT_SUCCESS);
}
if(childSigAlrm) {
sigset_t sig;
init_sigset(&sig, SIGUSR2);
sigprocmask(SIG_UNBLOCK, &sig, NULL);
}
}
}
init_signal(&action, &par_signal);
bind_signal(&action, 2, SIGALRM, SIGCHLD);
while(1) {
alarm(3);
pause();
/* handle and reset signal flags similar to child */
}
}
关于c - 使用 c 安排警报,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60740276/
我正在尝试将字符串转换为 float 。我知道 parseFloat() 可以做到这一点,但我也找到了下面的语法,但没有太多引用。 什么是正确的语法,因为它们似乎都有效。我可以在哪里了解更多相关信息?
我见过一些看起来很酷的“窗口”/“警报”/不管它们叫什么。我希望我知道。以下是其中的一些示例: 这些不应该是 Apple 独有的,因为我已经看到 3rd 方应用程序使用它们!我想知道这些 window
这个问题已经有答案了: What is the difference between a function call and function reference? (6 个回答) 已关闭 7 年前。
alert('test1'); var re = new RegExp("(http://(?:[A-Za-z0-9-]+\\.)?[A-Za-z0-9-]+\\.[A-Za-z0-9-]+/?)",
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我的作业有问题...我不知道我的代码有什么问题..我的作业是创建一个简单的学习数学和级别选择......我使用下拉菜单来选择级别和算术运算......现在我的问题是,当我单击按钮时,它将转到函数sta
我有一些复选框,其值属性来自数据库。我希望用户始终检查具有相同值的复选框(如果他不使用 javascript 发出警报)。我尝试使用以下 javascript 代码执行此操作,但没有用 fu
这有点难以解释,我的网站上有一个幻灯片形式的多部分表单。他们必须使用单选按钮从 3/4 选项中进行选择。 我对它们进行了一些验证,以确保用户在允许转到下一张幻灯片之前选择一个。 如果我单击一个对象来选
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
我的页面上有一个click链接,我想在单击时播放通知或提示音。我如何使用jQuery做到这一点? 在此先感谢... :) 炸药 最佳答案 使用 jQuery sound 插件。 关于javascrip
我正在尝试在 Excel 列中创建 VBA -Alert 弹出窗口。在基于某些计算的 Excel 工作表中,将计算一些增长%(H 列),如果增长%> 20%,则会生成一个警报弹出窗口,询问原因代码,需
当用户滚动到网页的特定部分时,如何使用 JavaScript 显示警报。我尝试通过检查 document.body.clientWidth = document.documentElement.cli
我正在尝试制作一个脚本,其中会弹出一个提示窗口询问问题,并根据其中的答案,会弹出一个警告框,指出答案有效或无效。在我的代码中,我的提示框有效,但我的警报框没有。有人可以帮我解决这个问题吗?非常感谢!!
我正在尝试 Grafana 的警报和通知功能,它看起来真的很棒。 松弛通知示例。 但是有一个大问题。它需要使用 S3 进行配置,这使得任何人都可以公开访问图像。对于那些不希望公开访问其图像的公司来说,
我想知道是否有任何方法可以在 adobe reader 中通知用户pdf 表单已提交到服务器?我正在提交一个正常的 http/html 形式到 php 脚本没什么大不了的,直接,但文档、论坛等似乎存在
在 TFS 中构建失败后,是否可以通过电子邮件获取构建成功的信息? 当构建失败时(我确实如此),我可以收到电子邮件。当构建成功时,我可以收到电子邮件。 但我需要知道构建不再失败。如果我收到构建失败的电
我需要一些帮助来理解 jQuery 如何存储元素。请看一下这个链接: http://jsfiddle.net/NubWC/ 我试图从所有具有特定类的标题标签中获取元素 id,并将其放入数组中,以便我可
我想做 alert(this) 来进行演示(想看看代码中不同位置的“this”是什么)。 有什么想法可以实现这一目标吗? 现在它只返回[object Object]? 最佳答案 这样做: consol
当出现警告框时,有什么方法可以阻止 Enter 键盘吗?因此用户需要按 Esc 键或单击 Ok 按钮来删除警报。 alert('Hello'); 最佳答案 正如我之前的评论所述,标准的 javas
我正在尝试在 javascript 中创建一个函数并传入参数“name”,然后当用户点击一张照片时,会出现一条警告,类似于“这张照片是在 ____ 拍摄的” function photoWhere
我是一名优秀的程序员,十分优秀!