c - 它是一种在c语言中挂起相同类型信号的方法吗?
问题描述
当另一个相同类型的信号在处理程序中时,我真的需要使信号挂起。
假设 SIGUSR2 在处理程序中,而 SIGUSR1 是 sa_mask 的成员。如果现在进程收到 SIGUSR1,它将被阻塞并在 SIGUSR2 从处理程序退出后交付,这是合理的。
但是,如果进程在处理程序中处理另一个 SIGUSR2 时收到 SIGUSR2,则第二个信号将永远被忽略。
我希望 SIGUSR2 被挂起并稍后交付。我怎样才能做到这一点?
注意:以下代码只是两个示例,如果您理解我的问题,则无需阅读它们
第一种情况:孩子向父母发送两个信号(SIGUSR1 和 SIGUSR2)。当 SIGUSR1 在处理程序中时, SIGUSR2 将被挂起并稍后交付:
#define MAXCHILD 1
void handler1(int signo)
{
switch(signo)
{
/* handling SIGUSR1 takes one second
during this time if SIGUSR2 will be blocked on delivery. */
case SIGUSR1:
write(1,"SIGUSR1 received \n",strlen("SIGUSR1 received \n"));
sleep(5);
break;
case SIGUSR2:
write(1,"SIGUSR2 received \n",strlen("SIGUSR2 received \n"));
break;
}
}
int main()
{
struct sigaction action1;
sigset_t set1;
sigemptyset(&set1);
sigaddset(&set1, SIGUSR2);//adding SIGUSR2 to set1
sigaddset(&set1,SIGUSR1);
action1.sa_handler = handler1;
action1.sa_mask = set1;
action1.sa_flags = 0;
int inchild=0;
sigaction(SIGUSR1,(struct sigaction *) &action1,NULL);
sigaction(SIGUSR2,(struct sigaction *) &action1,NULL);
pid_t parent=getpid();
pid_t pid[MAXCHILD];
for ( int i=0;i<MAXCHILD;i++)
{
pid[i]=fork();
if( pid[i]==0)
{
inchild=1;
break;
}
}
while(inchild==0);
if(inchild==1)
{
//child sends SIGUSR1 and immediately SIGUSR2 to parent
kill(parent,SIGUSR1);
kill(parent,SIGUSR2);
sleep(1);
}
printf("end\n");
return 0;
}
上面代码的输出是:
SIGUSR1 received
end
SIGUSR2 received
没关系。
但是让我们谈谈第二种情况:孩子向父母发送两个信号(SIGUSR1)。当 SIGUSR1 在处理程序中时,第二个 SIGUSR1 将不会挂起,将永远被忽略:
#define MAXCHILD 1
void handler1(int signo)
{
switch(signo)
{
/* handling SIGUSR1 takes one second
during this time if SIGUSR2 will be blocked on delivery. */
case SIGUSR1:
write(1,"SIGUSR1 received \n",strlen("SIGUSR1 received \n"));
sleep(5);
break;
case SIGUSR2:
write(1,"SIGUSR2 received \n",strlen("SIGUSR2 received \n"));
break;
}
}
int main()
{
struct sigaction action1;
sigset_t set1;
sigemptyset(&set1);
sigaddset(&set1, SIGUSR2);//adding SIGUSR2 to set1
sigaddset(&set1,SIGUSR1);
action1.sa_handler = handler1;
action1.sa_mask = set1;
action1.sa_flags = 0;
int inchild=0;
sigaction(SIGUSR1,(struct sigaction *) &action1,NULL);
sigaction(SIGUSR2,(struct sigaction *) &action1,NULL);
pid_t parent=getpid();
pid_t pid[MAXCHILD];
for ( int i=0;i<MAXCHILD;i++)
{
pid[i]=fork();
if( pid[i]==0)
{
inchild=1;
break;
}
}
while(inchild==0);
if(inchild==1)
{
//child sends SIGUSR1 and immediately SIGUSR1 to parent
kill(parent,SIGUSR1);
kill(parent,SIGUSR1);
sleep(1);
}
printf("end\n");
return 0;
}
我希望输出是:
SIGUSR1 received
end
SIGUSR1 received
但输出是:
SIGUSR1 received
end
这表明第二个信号已被永远忽略。
发送两个相同类型的信号时如何达到预期结果?我只是希望能够将第二个信号作为待处理信号,有没有办法做到这一点?
根据这个链接,没有办法做到这一点,但我希望有人提供一种虚假的方式来做到这一点,或者至少模拟它(但我希望 write() 函数保留在处理程序中)。
解决方案
推荐阅读
- vuetify.js - Vuetify/autocomple 组件如何自带`v-list-item`
- python - 无法在 python 中加载 ssl 证书:TypeError: certfile should be a valid filesystem path
- python - 按列标题加入熊猫数据框
- haskell - 无法使用堆栈构建带有模块导入的项目(在 Windows 上)
- windows - 从以 SYSTEM 身份运行的 Powershell 设置用户环境变量
- java - Android RecyclerView DiffUtil.Callback: areContentsTheSame() 和 getChangePayload() 给出不同的比较结果
- docker - 如何将 docker run 参数添加到 docker compose 文件中?
- javascript - Floara 编辑器插件(列表)按钮未在反应 js 中显示(下一个 JS)
- ionic4 - 自动关注 Ionic Angular 应用程序中的输入字段,同时打开搜索弹出窗口
- c# - Aspose.Cells NuGet 18.3 Worksheet 对象似乎对 .Net Core 有不同的 API