Signals

Overview to Signals

D-SP-Ch9aa-Overview

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

D-SP-Ch9af-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;
}

Reliable Signals

D-SP-Ch9ag-Reliable_Signals

Some System Calls

kill, raise

D-SP-Ch9ah-kill_raise

alarm, pause

D-SP-Ch9ai-alarm_pause