【问题标题】:Sleep instruction doesn't work with signal handler [closed]睡眠指令不适用于信号处理程序[关闭]
【发布时间】:2020-05-29 05:49:39
【问题描述】:
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秒,然后出去。

这段代码跳过睡眠指令,为什么?

【问题讨论】:

  • 正确格式化和缩进的代码比你这里的更容易阅读和理解。
  • 所以它不会等待 3 秒?
  • 编译器应该拒绝setup_sig();您不能从以void 作为返回类型的函数返回值(另请参阅Reading parameter from file and creating filenames,它引用了标准的相关部分)。另外What should main() return in C or C++? — 答案不是void,可能在 Windows 上除外。
  • 我们是否可以让minimum, reproducible example 具有完整的标头、编译器标志、没有编译警告,以及您期望的行为与您观察到的行为的详细描述?像@user253751 一样,我不太明白你所说的睡眠“不起作用”或代码“跳过睡眠指令”是什么意思。

标签: c linux signals sleep


【解决方案1】:

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

┌──────────┬───────────────┬─────────────────────────────┐
│Interface │ Attribute     │ Value                       │
├──────────┼───────────────┼─────────────────────────────┤
│sleep()   │ Thread safety │ MT-Unsafe sig:SIGCHLD/linux │
└──────────┴───────────────┴─────────────────────────────┘

sig:SIGCHLD/linux 在这种情况下很重要。根据here,解释如下(我的重点):

sig:标有 sig 为 MT 安全问题的函数可能会出于内部目的临时安装信号处理程序,这可能会干扰信号的其他用途,在冒号后标识。

可以通过确保在通话期间不会对信号进行其他用途来解决此安全问题。在调用使用相同临时信号的所有函数时持有非递归互斥锁; 建议在调用之前阻止该信号并在之后重置其处理程序。

可以通过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.
}

【讨论】:

  • 那么我该如何实现呢?
  • @paramikoooo,我认为粗体字说明了这一点,我会详细说明。
猜你喜欢
  • 1970-01-01
  • 2015-11-23
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多