Signals
Overview to Signals
Conditions to Generate Signals
In what condition will we generate signals?
D-SP-Ch9ab-Conditions_to_Generate_Signals
Disposition of a Signal
What should we do when the process received signals
D-SP-Ch9ac-Disposition_of_a_Signal
Example of Signals
D-SP-Ch9ad-Examples_of_Signals
Interrupted System Calls
D-SP-Ch9ae-Interrupted_System_Calls
What is a good signal handler?
- 不是 non-reentrant function
- 在開始執行時先記錄當時的
errno並且在結束時將errno設為我們記錄的,原因是在執行 signal handler 時可能會改動到errno - 不使用
longjmp(),我們不知道 signal handler 會在哪裡被呼叫,因此使用如果更新重要東西到一半被 interrupt 並且longjmp()可能會造成這個重要東東永久 crash
Reentrant Functions
Signal handler must be reentrant functions
雖然 compiler 不會要求 signal handler 必須是 reentrant function,但是 signal handler 是 non-reentrant function 有機率產生 deadlock 及 race condition
因為我們不知道我們會在 process 執行到哪裡會被 interrupt,所以是 non-reentrant function 的 signal handler 可能就會莫名其妙造成 process crash 掉
Reentrant Function
Unreliable & Reliable Signals
Unreliable Signals
在 signal (unreliable) 中我們介紹的 system call 是 not reliable 的並且是已經被新版本的 Linux 替換掉的,我們說這種 signal 會 “get lost”,以下給出兩個範例
Signal occurred before resetting signal handler
在下方的程式中,如果我們在 line 5 和 line 6 間突然被 SIGINT interrupt,那麼我們還不及重新設定 signal handler,我們的 process 就會意外死掉
int sig_int();
...
signal(SIGINT, sig_int);
...
sig_int() {
signal(SIGINT, sig_int);
}Race Condition
下方程式如果在 line 7 和 line 8 間接收到 SIGINT,那麼這個 process 就會永遠卡在 pause()
int sig_int_flag;
main() {
...
signal(SIGINT, sig_int);
...
while (sig_int_flag == 0)
pause();
}
sig_int() {
signal(SIGINT, sig_int);
sig_int_flag = 1;
}