最好使用sigaction函式替代signal函式

2021-09-05 09:13:04 字數 1760 閱讀 2437

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...