C中的SIGALRM不在处理程序中执行
在我使用SIGSTOP停止子进程之后,我希望使用SIGALRM每隔3秒执行一次子进程, 但是处理程序不起作用。这是我的密码:C中的SIGALRM不在处理程序中执行,c,linux,bash,multithreading,signals,C,Linux,Bash,Multithreading,Signals,在我使用SIGSTOP停止子进程之后,我希望使用SIGALRM每隔3秒执行一次子进程, 但是处理程序不起作用。这是我的密码: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <sys/wait.h> void singAlrm(int sig) { printf("HELLO from SI
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void singAlrm(int sig)
{
printf("HELLO from SIGALRM");
kill(getpid(), SIGCONT);
}
int main()
{
int Sense1 = 1;
int Sense2 = 0;
int pid1 = fork();
signal(SIGALRM, singAlrm);
if (pid1 == 0)// fils1
{
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense1 == 1)
{
printf("sense 1 working \n");
Sense1 = 0;
}
else
{
printf(" sense 1 not working\n");
Sense1 = 1;
}
}
exit(0);
}
else// pere
{
int pid2 = fork();
if (pid2 == 0)
{
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense2 == 1)
{
printf("sense 2 is not working\n");
Sense2 = 0;
}
else
{
printf("sense 2 is working\n");
feuCouleurSenseBA = 1;
}
}
exit(0);
}
else
{
while (1)
{
sleep(3);
signal(SIGALRM, singAlrm);
kill(pid2, SIGALRM);
kill(pid1, SIGALRM);// here I have a problem when I call SIGALRM
}
}
}
}
您可能希望用
SIGCONT
(而不是SIGALRM
)替换从父进程发送给其子进程的信号:用SIGSTOP
停止的进程将无法处理任何类型的信号
下面是当我运行一个命令并向它发送一个SIGSTOP
时发生的情况(使用Ctrl+Z
):
$sleep 360
^Z
[1] +停止睡眠360
$pkill-信号睡眠
#无所事事
当程序恢复时,信号将被处理:
$pkill-SIGCONT睡眠
[1] -中断睡眠360
以下是使用修改后的代码的程序所发生的情况:
$/a.out
第二感正在发挥作用
第1感工作
第二感正在发挥作用
感觉1不工作
第二感正在发挥作用
第1感工作
由于子进程是通过SIGSTOP
停止的,它们只有在通过发送SIGCONT
唤醒时才会执行任何操作,您应该使用
kill(pid1, SIGCONT);
kill(pid2, SIGCONT);
在向父进程发送报警信号之前,为SIGALRM
设置处理程序不会影响任何事情。您没有设置警报,因此不会从中收到警报信号。它没有明确定义如果你使用它会发生什么。由于父级没有被困在等待SIGCONT
,因此将信号发送到自身的父级将不会有帮助,尤其是在发送信号的处理程序未被调用的情况下
请注意,您不应该从信号处理程序调用printf()
,请参阅以了解更多信息。如果确实调用了printf()
,则需要以换行符结束输出,以确保它已被打印-或者使用fflush()
下面是似乎有效的代码:
#include "stderr.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
static void singAlrm(int sig)
{
printf("HELLO from SIGALRM %d\n", sig);
//kill(getpid(), SIGCONT);
}
int main(int argc, char **argv)
{
if (argc > 0)
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MILLI);
int Sense1 = 1;
int Sense2 = 0;
int pid1 = fork();
signal(SIGALRM, singAlrm);
if (pid1 == 0)// fils1
{
err_remark("Child 1 at work - Sense1 = %d\n", Sense1);
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense1 == 1)
{
printf("sense 1 working\n");
Sense1 = 0;
}
else
{
printf("sense 1 not working\n");
Sense1 = 1;
}
err_remark("Child 1 - Sense1 now %d\n", Sense1);
}
exit(0);
}
else// pere
{
int pid2 = fork();
if (pid2 == 0)
{
err_remark("Child 2 at work - Sense2 = %d\n", Sense2);
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense2 == 1)
{
printf("sense 2 is not working\n");
Sense2 = 0;
}
else
{
printf("sense 2 is working\n");
Sense2 = 1;
}
err_remark("Child 2 - Sense2 now %d\n", Sense2);
}
exit(0);
}
else
{
while (1)
{
err_remark("Parent about to sleep\n");
sleep(3);
err_remark("Parent woke up\n");
//signal(SIGALRM, singAlrm);
kill(pid2, SIGCONT);
kill(pid1, SIGCONT);
}
}
}
}
给出或获取调试信息,这正是您所追求的。请注意,两个子进程响应的顺序不能保证
请注意,从未调用报警处理程序。由SIGSTOP停止的进程在收到SIGCONT之前不会执行任何操作。您可能想使用或相反,甚至更好,找到一种根本不使用信号的方法。是的,我知道,但我在处理程序中使用了SIGCONT,但我不知道它为什么不执行。建议使用sigaction()而不是signal()。Ubuntu 20.04上的“man signal”中写道:“signal()的唯一可移植用途是将信号的配置设置为SIG_DFL或SIG_IGN。使用signal()建立信号处理程序时的语义因系统而异(POSIX.1明确允许这种变化);不要将其用于此目的。”@karim在停止的进程收到某个未停止的进程发送的SIGCONT之前,SIGALRM处理程序不会运行代码>真的是
Sense2=1代码>?
#include "stderr.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
static void singAlrm(int sig)
{
printf("HELLO from SIGALRM %d\n", sig);
//kill(getpid(), SIGCONT);
}
int main(int argc, char **argv)
{
if (argc > 0)
err_setarg0(argv[0]);
err_setlogopts(ERR_PID|ERR_MILLI);
int Sense1 = 1;
int Sense2 = 0;
int pid1 = fork();
signal(SIGALRM, singAlrm);
if (pid1 == 0)// fils1
{
err_remark("Child 1 at work - Sense1 = %d\n", Sense1);
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense1 == 1)
{
printf("sense 1 working\n");
Sense1 = 0;
}
else
{
printf("sense 1 not working\n");
Sense1 = 1;
}
err_remark("Child 1 - Sense1 now %d\n", Sense1);
}
exit(0);
}
else// pere
{
int pid2 = fork();
if (pid2 == 0)
{
err_remark("Child 2 at work - Sense2 = %d\n", Sense2);
while (1)
{
kill(getpid(), SIGSTOP);
if (Sense2 == 1)
{
printf("sense 2 is not working\n");
Sense2 = 0;
}
else
{
printf("sense 2 is working\n");
Sense2 = 1;
}
err_remark("Child 2 - Sense2 now %d\n", Sense2);
}
exit(0);
}
else
{
while (1)
{
err_remark("Parent about to sleep\n");
sleep(3);
err_remark("Parent woke up\n");
//signal(SIGALRM, singAlrm);
kill(pid2, SIGCONT);
kill(pid1, SIGCONT);
}
}
}
}