c - sleep 指令不适用于信号处理程序

标签 c linux signals sleep

关闭。这个问题需要details or clarity .它目前不接受答案。












想改进这个问题?通过 editing this post 添加详细信息并澄清问题.

2年前关闭。




Improve this question



void handler ( int sig, siginfo_t * info, void * se)
{

}

int setup_sig(){
    struct sigaction sa;
    sa.sa_sigaction = handler;
    sa.sa_flags = SA_SIGINFO;
    sigfillset(&sa.sa_mask);
    if(-1 == sigaction(SIGCHLD, &sa , NULL)){return 0;} return 1;
}

void main()
{
    printf("before\n");
    setup_sig();
    sleep(3);
    printf("after\n");
}

此代码需要注册才能发出信号SIGCHLD然后睡3秒,然后出去。

此代码跳过 sleep 指令,为什么?

最佳答案

Linux documentation for sleep 在底部列出以下属性:

┌──────────┬───────────────┬─────────────────────────────┐
│Interface │ Attribute     │ Value                       │
├──────────┼───────────────┼─────────────────────────────┤
│sleep()   │ Thread safety │ MT-Unsafe sig:SIGCHLD/linux │
└──────────┴───────────────┴─────────────────────────────┘
sig:SIGCHLD/linux在这种情况下很重要。根据 here ,解释如下(我的重点):

sig: Functions marked with sig as a MT-Safety issue may temporarily install a signal handler for internal purposes, which may interfere with other uses of the signal, identified after a colon.

This safety problem can be worked around by ensuring that no other uses of the signal will take place for the duration of the call. Holding a non-recursive mutex while calling all functions that use the same temporary signal; blocking that signal before the call and resetting its handler afterwards is recommended.


可以使用 sigprocmask 来阻止信号。调用,例如:
// Need signal.h for this stuff.

sigset_t mask;

if ((sigemptyset(&mask) == -1) || (sigaddset(&mask, SIGCHLD) == -1)) {
    // handle failure here.
}

if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
    // handle failure here.
}

sleep(3);

// Probably need to re-establish CHLD signal handler as well as unmasking.

if (sigprocmask(SIG_UNBLOCK, &mask, NULL) == -1) {
    // handle failure here.
}

关于c - sleep 指令不适用于信号处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60209210/

相关文章:

c++ - 如何在 Linux 中使用 C++ 下载受密码保护的 URL?

linux - 无法在 syslog 消息中获取 Rsyslog 结构化数据

c - 为什么 SIGINT 被发送到子进程并且什么都不做?

捕获linux中的所有信号

java - 如何使用 jvalue 数组将两个整数传递给构造函数?

c - function(&x) 中的指针 &x 是什么时候创建的?

linux - Linux 系统监视器如何获取进程统计信息

c++ - 当远程桌面 session 注销时,如何阻止 DLL 终止应用程序服务器?

c - c中的简单循环链表

c - 如何用C更好的方式将字符串插入字符串?