在kill(getpid(),sig)之后,是否保证在下一个语句之前传递信号?

时间:2012-06-28 16:03:16

标签: linux process signals

假设您处于单线程进程中,并且相关信号未被阻止或忽略,是否可以保证:

kill(getpid(), sig);

会导致在执行下一行代码之前传递信号吗?

特别是,如果信号是没有处理程序的信号,并且整个默认操作是终止进程(例如SIGTERM,SIGALRM),是否保证下一行代码不会被执行?

我一直认为(至少在Linux上)答案是“是”,因为我认为在从任何系统调用返回之前,内核总是会检查是否有任何未决信号,如果有的话就交付它们。但我我观察到(当在一个负载很重的多核系统上运行时)情况并非总是如此,尽管这很难再现,所以我很感激确认我没有看到事情。

[这个问题与Is a signal sent with kill to a parent thread guaranteed to be processed before the next statement?非常相似,不过那个问题是询问多线程进程(答案肯定是“不”),而这个问题是关于单线程进程的。] < / p>

3 个答案:

答案 0 :(得分:0)

我现在认为答案确实是“是”。之前我曾想过信号是畅通无阻的,但我现在意识到可能并非如此,而且这很可能是我所看到的行为的原因。

答案 1 :(得分:0)

是。如果您使用的是单线程流程POSIX gives guarantees you this

  

如果pid的值导致为发送生成sig   进程,如果没有为调用线程阻止sig,如果没有   其他线程已取消阻止或正在sigwait()函数中等待   对于sig,要么是sig,要么是至少一个待处理的未阻塞信号   在kill()返回之前传递给发送线程。

答案 2 :(得分:0)

我已经制作了这个测试代码:

#include <signal.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

sig_atomic_t suspended = 0;

void handle() {
    printf("SIG");
}

int main(int argc, char **argv) {
    signal(SIGUSR1, handle);
    printf("BEFO");
    kill(getpid(), SIGUSR1);
    //pthread_kill(pthread_self(), SIGUSR1);
    printf("AFTR\n");
    return 0;
}

当我在 4 核笔记本电脑上的 bash 循环中运行它时,它似乎总是打印 BEFOSIGAFTR 而从不打印 BEFOAFTRSIG。

但请注意,该测试在几个方面存在缺陷:

  • 它确实在我的 PC 上运行的事实并不意味着它是有保证的(除非它在 ​​POSIX 文档中说明)
  • 系统在测试过程中没有承受过重负载
  • STDIO 做了一些缓冲
  • printf() 不是信号安全的(man 7 信号安全)