C 如何使用带有信号的叉子?
我不确定是否还有更复杂的信号和问题。孩子或家长的信号呼叫有区别吗 当一个子对象被分叉时,它现在是父对象,而只是前一个父对象的子对象吗 由于包含处理程序,默认处理程序是否无效。那么,您能否将C 如何使用带有信号的叉子?,c,signals,fork,C,Signals,Fork,我不确定是否还有更复杂的信号和问题。孩子或家长的信号呼叫有区别吗 当一个子对象被分叉时,它现在是父对象,而只是前一个父对象的子对象吗 由于包含处理程序,默认处理程序是否无效。那么,您能否将SIGINT更改为不终止进程 int count = 0; void killhandler(int sig){ printf("SIGKILL received\n"); return; } void childhandler(int sig){ int status; w
SIGINT
更改为不终止进程
int count = 0;
void killhandler(int sig){
printf("SIGKILL received\n");
return;
}
void childhandler(int sig){
int status;
wait(&status);
count += WEXITSTATUS(status);
return;
}
main(){
int i; // for loop iterator
pid_t pid[3]; // pids of child processes
Signal(SIGKILL, killhandler);
Signal(SIGCHLD, childhandler);
// Fork 3 child processes
for(i=0; i<3; i++){
pid[i] = fork();
if(!pid[i]){ // If child process
Signal(SIGKILL, SIG_DFL);
exit(5);
}
}
// Parent process only
for(i=0; i<3; i++){
kill(pid[i], SIGKILL);
}
sleep(5);
printf("count = %d\n", count);
exit(0);
}
int count=0;
无效killhandler(int-sig){
printf(“收到SIGKILL\n”);
返回;
}
void childhandler(int-sig){
智力状态;
等待(&状态);
计数+=WEXITSTATUS(状态);
返回;
}
main(){
int i;//for循环迭代器
pid_t pid[3];//子进程的pid
信号(SIGKILL,killhandler);
信号(SIGCHLD,childhandler);
//Fork 3子进程
对于(i=0;i当子进程分叉时,它非常接近父进程的精确副本。对于单线程进程,有三个关键区别:
父进程ID不同
进程ID不同
fork()
的返回值不同
(有关其他差异,请参阅POSIX手册页。)子系统中的信号处理程序与父系统中的信号处理程序相同。但是,子系统当然可以独立地更改其任何信号处理程序
不能将信号处理程序设置为捕获SIGKILL。该信号永远不会被捕获
孩子或家长的信号呼叫有区别吗
就它如何影响接收信号的过程而言,没有
当一个子对象被分叉时,它现在是父对象,而只是前一个父对象的子对象吗
它肯定是父母的孩子。它是否成为父母取决于它是否为自己的孩子分叉
由于包含处理程序,默认处理程序是否无效。因此,能否将SIGINT更改为不终止进程
int count = 0;
void killhandler(int sig){
printf("SIGKILL received\n");
return;
}
void childhandler(int sig){
int status;
wait(&status);
count += WEXITSTATUS(status);
return;
}
main(){
int i; // for loop iterator
pid_t pid[3]; // pids of child processes
Signal(SIGKILL, killhandler);
Signal(SIGCHLD, childhandler);
// Fork 3 child processes
for(i=0; i<3; i++){
pid[i] = fork();
if(!pid[i]){ // If child process
Signal(SIGKILL, SIG_DFL);
exit(5);
}
}
// Parent process only
for(i=0; i<3; i++){
kill(pid[i], SIGKILL);
}
sleep(5);
printf("count = %d\n", count);
exit(0);
}
SIGINT的默认处置是终止进程,但您可以捕获并处理SIGINT,也可以阻止或忽略它。默认处置与其说是无效的,不如说是重写的,直到(如果)您再次更改它
为什么从未打印“收到SIGKILL”
你不能阻止、忽略或捕获SIGKILL。你不会看到你的处理程序打印任何东西,因为它永远不会被SIGKILL调用。SIGSTOP同样不能被忽略、阻止或处理。这是这方面的两个特殊信号
在您的程序中,您试图将SIGKILL设置为其默认值,事实上,它是子系统中唯一的配置。由于您的子系统立即退出,来自父系统的信号可能永远不会被传递,因为子系统已经死亡,并且父系统中的kill
可能因ESRCH而失败,例如,没有具有该pid的子系统存在任何lo一个sleep
在那里会很有帮助,这样他们就可以活得足够长以至于被杀。(我喜欢这个术语。)
您使用的WEXITSTATUS
是错误的。如果您的目的是统计自愿退出而不是被杀的孩子的数量,那么您可能只需要使用WIFEXITED或WIFSIGNALED的简单计数器。WEXITSTATUS返回自己退出的孩子的状态代码。它可以是0、1、50或75。添加它就可以了o变量可能不是您想要的
信号是一个令人困惑的话题,因为洋葱有好几层,规则和平台特定语义有足够多的例外,使它们令人沮丧。我从来没有找到一个完整地涵盖它们的来源。也就是说,信号处理和处理程序是洋葱的外层,有许多网络上提供的资源涵盖了这些方面