apue 習題15.15,乙個xsi共享儲存的測試程式:
#include
#include
#include
#include
#include
#include
#include
#include
#include
static
volatile sig_atomic_t sigflag;
static sigset_t newmask, oldmask, zeromask;
static
void
sig_usr
(int signo)
bool tell_wait()
void
tell
(pid_t pid)
void
wait()
static
intupdate
(int
*ptr)
intmain()
shmdt
(area);}
else
shmdt
(area)
;shmctl
(shmid, ipc_rmid,0)
;}return0;
}
gcc -std=c99 -d_xopen_source test.c
執行結果不對:
parent shm addr: 0x7f9a4476e000
parent 0
child shm addr: 0x7f9a4476e000
child 1
parent 2
然後檢視子程序處於狀態,子程序退出了,父程序還在wait。
修改父程序,呼叫wait()獲取子程序狀態是10,正好是訊號sigusr1的值,懷疑是子程序收到sigusr1就退出了,查了sigusr1的預設動作是終止程式。在wait()中sigsuspend返回之後重新設定訊號處理程式,輸出變正常了。
結合man和帖子signal()註冊的訊號處理函式裡面,不需要再次註冊訊號處理函式嗎? :
the kernel』s signal() system call provides system v semantics. system v會在處理訊號之後將訊號處理程式重置為sig_dfl。如果編譯時加了額外的選項例如-std=c99,那麼用核心的signal()系統呼叫。預設情況下使用sigaction函式的方式。
嘗試去掉-std=c99並調整**並沒有作用,可能是還帶了-d_xopen_source;以下兩種方式是可以的:
g++ test.c
gcc -std=gnu99 test.c
apue 10.14節對sigaction函式明確指出:一旦對給定的訊號設定了乙個動作,那麼在呼叫sigaction顯式地改變它之前,該設定一直有效。所以將
if(signal(sigusr1, sig_usr) != 0) return false;
替換為
struct sigaction act;
act.sa_handler = sig_usr;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if(sigaction(sigusr1, &act, null) != 0) return false;
也可以解決問題。
結論:最好使用sigaction函式替代signal函式。
sigaction函式使用例項
sigaction函式 1 sigaction函式原型 sigaction函式用來查詢和設定訊號處理方式,它是用來替換早期的signal函式。sigaction函式原型及說明如下 sigaction 查詢和設定訊號處理方式 所需標頭檔案 include 函式說明 sigaction 會依引數sign...
sigaction函式的使用
sigaction函式的功能是檢查或修改與指定訊號相關聯的處理動作 可同時兩種操作 他是posix的訊號介面,而signal 是標準c的訊號介面 如果程式必須在非posix系統上執行,那麼就應該使用這個介面 給訊號signum設定新的訊號處理函式act,同時保留該訊號原有的訊號處理函式oldact ...
sigaction函式使用例項
sigaction函式 1 sigaction函式原型 sigaction函式用來查詢和設定訊號處理方式,它是用來替換早期的signal函式。sigaction函式原型及說明如下 sigaction 查詢和設定訊號處理方式 所需標頭檔案 include 函式說明 sigaction 會依引數sign...