Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
精确地处理所有到达父进程的SIGUSR1类型的信号。C_C_Printf_Fork_Execl - Fatal编程技术网

精确地处理所有到达父进程的SIGUSR1类型的信号。C

精确地处理所有到达父进程的SIGUSR1类型的信号。C,c,printf,fork,execl,C,Printf,Fork,Execl,我想用fork()函数编写一个程序,它将创建N个子对象。每个子级将等待0到3秒,然后它将向其父级发送一个信号SIGUSR1。父级处理所有这些信号 问题是我的程序并不总是处理来自它的孩子们的所有信号。怎么修理 第二个问题:我知道我不应该在处理程序中使用printf,因为可能会发生一些不好的事情。如何替换此说明 main.c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include &l

我想用fork()函数编写一个程序,它将创建N个子对象。每个子级将等待0到3秒,然后它将向其父级发送一个信号SIGUSR1。父级处理所有这些信号

问题是我的程序并不总是处理来自它的孩子们的所有信号。怎么修理

第二个问题:我知道我不应该在处理程序中使用printf,因为可能会发生一些不好的事情。如何替换此说明

main.c

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void error(char *s){
    printf("%s\n",s);
    perror("Program execution failed.");
    exit(EXIT_FAILURE);
}

volatile int N=8; //final number of children
volatile int k=0; //number of received SIGUSR1 signals

void childRequestHandler(int signo, siginfo_t* info, void* context){
    k++;
    printf("%d,Father received request from child: %d\n",k,info->si_pid);

}

int main() {
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = childRequestHandler;
    if(sigaction(SIGUSR1,&act,NULL) == -1) printf("ERROR OCCURED");

    for(int i=0;i<N;i++){
        pid_t pid = fork();
        if(pid == 0) {
            execl("./child", "./child", NULL);
            error("Fork error happened\n");
        }
    }

    while (1){
        sleep(1);
    }

}

当信号处理程序执行时,信号被阻塞。在此期间接收到的所有
SIGUSR1
信号将不会被注意到

建立信号时,您可以使用
SA_NODEFER
标志,有关标志的信息,请参阅

但是,如果使用
sau NODEFER
,请不要使用
printf
!它不是异步信号安全函数。有关更多信息,请参见例如


发件人:

当信号被
sigaction()
安装的信号捕获功能捕获时,将在信号捕获功能的持续时间内计算并安装一个新的信号掩码。。。。该掩码是通过将当前信号掩码和正在传送的信号的
sa_掩码
的值进行并集而形成的,除非设置了
sa_NODEFER
sa_RESETHAND
,否则包括正在传送的信号。如果用户的信号处理程序正常返回,则恢复原始信号掩码


[Emphasis mine]

POSIX表示阻塞的信号在能够发送之前一直处于挂起状态,因此信号是可靠的。或者我误读了什么?@JonathanLeffler我会说这是关于其他信号的,而不是将被屏蔽的当前信号(见我编辑中的引文)。在这种情况下,当前信号和其他信号不应该被区别对待。但是,如果信号在挂起时再次生成(OPs程序中可能会发生这种情况,因为多个子系统可能会在任何一个子系统交付给父系统之前生成该信号),则其实现定义为该信号是否多次交付。事实上,大多数Unix系统不排队,除非它们支持实时扩展。在POSIX参考中,它记录了Paul所说的:如果随后生成了挂起信号,它是指信号是否在需要排队的情况以外的其他情况下多次发送或接收的实现。未指定SIGRTMIN到SIGRTMAX范围之外的多个同时挂起的信号传递给进程或被进程接受的顺序。没有注意到大多数Unix系统不进行排队。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>



int main() {
    time_t t;
    srand((unsigned int) getpid()+ time(NULL));


    int length_of_sleeping = rand() % 4 ;
    printf("I live: %d, sleeps %ds \n",getpid(),length_of_sleeping);
    sleep(length_of_sleeping);
    kill(getppid(),SIGUSR1);

    while(1){

    }

}
I live: 4195, sleeps 3s 
I live: 4196, sleeps 3s 
I live: 4197, sleeps 1s 
I live: 4202, sleeps 3s 
I live: 4198, sleeps 0s 
I live: 4201, sleeps 2s 
I live: 4199, sleeps 0s 
I live: 4200, sleeps 3s 
1,Father received request from child: 4198
2,Father received request from child: 4197
3,Father received request from child: 4201
4,Father received request from child: 4195