Linux信号 四 异步等待信号与同步等待信号接口
生活随笔
收集整理的這篇文章主要介紹了
Linux信号 四 异步等待信号与同步等待信号接口
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
信號的同步等待和異步等待區別就是信號處理函數的執行與否,異步等待是信號處理函數已經執行了,同步等待是信號處理函數還沒有執行。
異步等待接口:pause() 和 sigsuspend()
1. pause()
/*** 等待信號* pause()函數將調用進程/線程掛起,使之進入可中斷的睡眠狀態,直到傳遞了一個信號為止。* 這個信號的動作或者是執行用戶定義的信號處理函數,或者是終止進程。如果執行用戶定義的* 信號處理函數,pause()會在信號處理函數執行完畢后返回,如果是終止進程,pause()函數* 就不返回了,如果內核發出的信號被忽略,那么就不會被喚醒。* * 成功返回-1,并置errno為EINTER.** pause函數并不能區分是什么信號觸發中斷,所以不能使用pause函數來等待特定的信號。*/ #include <unistd.h> int pause(void);2. sigsuspend()
/*** 等待特定信號** sigsuspend暫時使用參數mask替換調用進程/線程的信號掩碼,并且阻塞直到特定信號* 發生。如果信號終結了進程,sigsuspend函數不返回,如果信號被捕獲,則sigsuspend* 會等到信號處理函數執行完成后才返回,并且調用進程/線程的信號掩碼會恢復到調用之前* 的樣子。* 信號SIGKILL 和 SIGSTOP是無法阻塞的。* 返回值-1,錯誤碼可以是EINTR(信號中斷)或者EFAULT(參數錯誤)**/ #include <signal.h> int sigsuspend(const sigset_t *mask);同步信號接收接口有兩類:
1. sigwait() 、sigwaitinfo()、sigtimedwait(),這三個函數接口略有差異,做的事情類似。都是等待特定信號,如果沒有信號則掛起當前進程,有的話立即返回。
/*** 等待信號發生* * 成功返回0,并將信號值存儲到參數set中,失敗返回一個正的錯誤碼。* */ #include <signal.h> int sigwait(const sigset_t *set, int *sig);?
/*** 等待信號返回* * 當參數第二個siginfo_t不為空時,內核會將關于該信號更詳細的信息存儲到該指針指向地址,* 如果有多個信號滿足條件,sigwaitinfo只會返回其中一個。* 成功返回信號值,失敗返回-1并置errno* */ #include <signal.h> int sigwaitinfo(const sigset_t *set, siginfo_t *info);/*** 和sigwaitinfo功能一樣,只是多了一個時間參數,超時未等到信號立即返回,* 如果時間參數timeout為NULL,則和sigwaitinfo一樣。* 如果timeout兩個參數為0,那么sigtimedwait會立即返回。**/struct timespec {long tv_sec; /* seconds */long tv_nsec; /* nanoseconds */ }int sigtimedwait(const sigset_t *set, siginfo_t *info,const struct timespec *timeout);通常調用上述接口前都需要先調用sigprocmask接口將關注的信號屏蔽,防止被信號處理函數劫走。
2. Linux還提供了另外一種同步等待信號接口 signalfd
/*** 創建一個用于接收信號的文件描述符。** 參數fd = -1時,該函數會創建一個文件描述符。* fd != -1,表示修改操作,一般是修改mask的值,此時fd是之前signalfd的* 返回值** 參數mask表示信號集,關注的信號集合。這些信號的集合應該在調用signalfd函數* 之前,先調用sigprocmask函數阻塞這些信號,防止被信號處理函數劫走。** 參數flags用來控制行為,目前支持的標志位如下:* SFD_CLOEXEC :和普通文件的O_CLOEXEC一樣,調用exec函數時,文件描述符* 會被關閉。* SFD_NONBLOCK : 控制將來的讀取操作,如果執行read操作時,并沒有信號到來,* 則立即返回失敗,并設置errno為EAGAIN。** 成功返回文件描述符fd,失敗返回-1并置errno** 返回的描述符fd可用于poll,epoll,select等函數,用來檢測描述符fd上面的可讀* 事件。* * 創建文件描述符后,可以使用read函數來讀取到來的信號。提供的緩沖區大小最少要* 放下一個signalfd_siginfo結構體,該結構體如下,如果有多個信號返回,read會* 返回多個該結構體大小的字節數。*/ #include <sys/signalfd.h> int signalfd(int fd, const sigset_t *mask, int flags);struct signalfd_siginfo {uint32_t ssi_signo; /* Signal number */int32_t ssi_errno; /* Error number (unused) */int32_t ssi_code; /* Signal code */uint32_t ssi_pid; /* PID of sender */uint32_t ssi_uid; /* Real UID of sender */int32_t ssi_fd; /* File descriptor (SIGIO) */uint32_t ssi_tid; /* Kernel timer ID (POSIX timers)uint32_t ssi_band; /* Band event (SIGIO) */uint32_t ssi_overrun; /* POSIX timer overrun count */uint32_t ssi_trapno; /* Trap number that caused signal */int32_t ssi_status; /* Exit status or signal (SIGCHLD) */int32_t ssi_int; /* Integer sent by sigqueue(3) */uint64_t ssi_ptr; /* Pointer sent by sigqueue(3) */uint64_t ssi_utime; /* User CPU time consumed (SIGCHLD) */uint64_t ssi_stime; /* System CPU time consumed(SIGCHLD) */uint64_t ssi_addr; /* Address that generated signal(for hardware-generated signals) */uint16_t ssi_addr_lsb; /* Least significant bit of address(SIGBUS; since Linux 2.6.37)uint8_t pad[X]; /* Pad size to 128 bytes (allow foradditional fields in the future) */ };signalfd創建的文件描述符使用完成之后要調用close函數來關閉該文件描述符:
/* 關閉文件描述符 */ close(fd);參考資料:
1. 《Linux環境編程,從應用到內核》 高峰,李彬著
2. man signalfd : http://www.man7.org/linux/man-pages/man2/signalfd.2.html
總結
以上是生活随笔為你收集整理的Linux信号 四 异步等待信号与同步等待信号接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 万元和亿元的换算(万元)
- 下一篇: 这是我在一舍宾训练管拍的,这些衣服都是要