在Linux中,当一个信号被发送到一个进程/线程(无论什么原因)时,是立即调用的信号处理程序(假设有一个,信号没有被阻塞)?
我的意思是,我很确定,在处理信号的进程/线程中,它将被立即调用,但我的意思是相对于其他进程/线程。
如果处理程序立即被调用,它是否也会使相应的进程/线程处于活动状态(以便正常执行立即继续)?
编辑
由于我原来的问题似乎被误解了,我会试着用一个例子来再次解释。
让我说在我的电脑我有一个单一的CPU,和2进程运行,处理“A”和处理“B”。 并假设他们都没有阻塞在系统调用(如sleep
)。 通常情况下,操作系统会在执行进程“A”和进程“B”之间切换,例如执行进程“A”100ms,然后进程“B”100ms,然后再执行A进程100ms等)。 假设进程“A”现在是活动进程(即现在是占用CPU的进程)。 现在说进程'A'发送一个信号来处理'B'(或者,或者,OS不pipe什么原因都会发送这个信号来处理'B')。 进程'B'已经注册了该信号的处理程序,并没有阻止它。 所以问题是,操作系统现在是否立即停止执行进程“A”并切换到执行进程“B”的信号处理程序? 如果答案是肯定的,之后会立即继续执行进程“B”(正常代码,而不是信号处理程序),或者切换回执行进程“A”,并且只有在一小段时间恢复执行进程'B'?
然后可以提出关于线程而不是进程的相同问题。
不,仅在上下文切换时传送信号。 那时候所有的信号都会排队等候。 在许多同类型的信号中,通常只有一个信号被传送到目的地。 所以,我很舒服地坐在更多的信号被摧毁比交付。 我建议你参考有关任何Unix书籍的章节。 我最喜欢的是了解linux内核和linux内核的开发。 如果你仍然需要技术帮助,请评论一下
有两种情况:当信令进程处于活动状态时,以及何时被阻塞。
对于前一种情况,根据http://www.tldp.org/LDP/tlk/ipc/ipc.html ,该过程将在系统调用退出时处理该信号。 这意味着像a = b + c(或其等效机器码)的正常指令不会因为信号而中断。 信号处理也可能在CPU密集型的过程中被延迟。
但是,当进程被阻塞时,这取决于被调用的内核函数是否是可中断的(例如,wait_event_interruptible)。 如果它是可中断的,则进程将唤醒,否则,直到它离开不可中断的功能(例如,由于IRQ)。
是的,处理程序将立即被调用。 假设我有一个编码如下的进程。
#include <stdio.h> #include <signal.h> void handle_signal(int signal); volatile int i = 1; int main( ) { struct sigaction sa; // Setup the sighub handler sa.sa_handler = &handle_signal; // Block every signal during the handler sigfillset(&sa.sa_mask); while(1) { if(i == 1) { printf("A"); } } return 0; } void handle_signal(int signal) { /* * Please note that printf et al. are NOT safe to use in signal handlers. * Look for async safe functions. */ const char *signal_name; sigset_t pending; // Find out which signal we're handling switch (signal) { case SIGHUP: signal_name = "SIGHUP"; break; case SIGSTOP: i = 0; signal_name = "SIGSTOP"; break; case SIGCONT: signal_name = "SIGCONT"; i = 1; break; default: fprintf(stderr, "Caught wrong signal: %d\n", signal); return; } }
除非收到SIGSTOP
信号,否则一直打印在shell上。 因此,打开shell并kill -STOP <pid of above process>
验证进程是否停止,然后从shell使用kill -CONT <pid of above process>
发送SIGCONT
信号
And if the handler is called immediately, will it also make the corresponding process/thread active (so that its normal execution continues immediatly)
你的信号处理器有它自己的上下文。 所以没有线程必须被激活来处理你的信号。 但是有一些问题需要牢记。 如果你的线程正在等待一些系统调用,比如sleep
或者read/write
或者其他的阻塞操作,这个系统调用将被中断,并且这个调用的返回值给你提供信息,你的进程(不是线程)收到一个信号这个返回值是EINTR
。 如果你的线程只是在等待系统调用的时候运行或者休眠,没有其他事情发生! 简单地说,调用处理程序时不会在进程内调度线程。
感谢所有你的答案! 他们是信息丰富的,但我的意思是要问别的东西(对不起,这是我的错,我没有明确解释自己)。 我已经编辑了我原来的问题,包括一个例子。 (我没有发表这个消息作为评论,因为它适用于所有的答案)