Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.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
C 如何捕获来自子进程的所有信号,同时对多个文件描述符使用轮询?_C_Operating System_Signals_Signal Handling_Multiple Processes - Fatal编程技术网

C 如何捕获来自子进程的所有信号,同时对多个文件描述符使用轮询?

C 如何捕获来自子进程的所有信号,同时对多个文件描述符使用轮询?,c,operating-system,signals,signal-handling,multiple-processes,C,Operating System,Signals,Signal Handling,Multiple Processes,因此,我有这个任务,他们告诉我,我必须创建一个进程树(具有子进程数\u分叉),从底层工作进程向进程树的根发送一些消息,最后在工作进程退出之前,他们必须向根进程发送一个SIGUSR1信号。经过一些(与我的问题无关)打印后,必须打印接收到的信号数量 首先,我设置了信号处理程序,调用这个例程(我在网上找到的,我认为它工作得很好): void set\u signal\u handler(int-signo,void(*handler)(int,siginfo\u t*,void*)){ 结构动作法;

因此,我有这个任务,他们告诉我,我必须创建一个进程树(具有子进程数\u分叉),从底层工作进程向进程树的根发送一些消息,最后在工作进程退出之前,他们必须向根进程发送一个SIGUSR1信号。经过一些(与我的问题无关)打印后,必须打印接收到的信号数量

首先,我设置了信号处理程序,调用这个例程(我在网上找到的,我认为它工作得很好):

void set\u signal\u handler(int-signo,void(*handler)(int,siginfo\u t*,void*)){
结构动作法;
memset(&act,'\0',sizeof(act));
act.sa_sigaction=处理程序;
act.sa_flags=sa_SIGINFO;
//设置信号处理器
if(sigaction(signo,&act,NULL)<0){
佩罗尔(“sigaction”);
出口(1);
}
}
然后我使用for循环为每个子级创建一个未命名的管道数组,然后分叉子级,最后调用一个监视文件描述符的例程,以便以非阻塞方式读取。轮询的逻辑如下所示:

while(open_files>0) {
    int retval = poll(fds, number_of_children, 0);

    // try to read only if poll does not fail
    if (retval > 0) {
        for(int i = 0; i < number_of_children; i++){
            reading from children
        }
    }
}
while(打开文件>0){
int retval=轮询(fds,子项数,0);
//如果轮询未失败,请尝试只读
如果(返回值>0){
for(int i=0;i<子项的数量;i++){
儿童读物
}
}
}
通过这种方式,我读取所有写入的内容(尽管轮询有时会因信号而中断),读取时没有问题

实际问题是,当我打印接收到的根的SIGUSR1信号时,我没有得到一致的值。在为每个进程节点运行3个子进程的多次运行中,我得到的值从3到9(这是正确的)。有没有更安全的方法来处理信号,而不是使信号哑

注意:经过一些研究,我知道我不能让相同类型的信号挂起(我尝试使用sigqueue发送信号)。我还尝试在轮询期间忽略信号,并在轮询结束时重新设置处理程序,但是,当然,由于信号已被哑化,因此无法工作。我还查看了一个相对的堆栈帖子,并将我的信号计数器声明为volatile sig_atomic_t,但它仍然不一致


实时信号排队,但SIGUSR1不是实时信号。如果在保持SIGUSR1期间(在其处理程序运行时隐式地,或通过调用
sigprocmask
),接收到两个或多个信号实例,则它们将合并为一个。如果你的任务要求你计算收到的SIGUSR1信号的数量,我认为这是不可能的。您可以通过让每个进程在发送信号之前向共享管道写入一个字节,然后让目标进程从管道中读取并汇总这些字节来获得等效值。你能给我们看一下全部分配吗?你确定观察处理的信号数量的不一致性不是分配的一部分吗?因为在我看来,你正在努力解决的问题正是在一门涉及信号处理的课程中值得注意的问题。@JohnBollinger我认为你可能是对的。我做了更多的研究,得出了相同的结论。这是不可能捕捉到所有的usr1信号的工人发送,所以我会保持它,因为我的项目的重点是看看有多不可靠的信号。无论如何,感谢各位!
while(open_files>0) {
    int retval = poll(fds, number_of_children, 0);

    // try to read only if poll does not fail
    if (retval > 0) {
        for(int i = 0; i < number_of_children; i++){
            reading from children
        }
    }
}