中断的系统调用
系統調用可分為兩類:慢速系統調用和其他系統調用
- 慢速系統調用:可能會使進程永遠阻塞的一類,如果在阻塞期間收到一個信號,該系統調用就被中斷,不再繼續執行(早期);也可以設定系統調用是否重啟。如:read、write、pause、wait等等
- 其他系統調用:getpid、getppid、fork...
結合pause,回顧慢速系統調用:
- 想中斷pause,信號不能被屏蔽
- 信號的處理方式必須是捕捉(默認、忽略都不可以)
- 中斷后返回-1,設置errno為EINTR(表“被信號中斷”)
可修改sa_flags參數來設置被信號中斷系統調用是否重啟。SA_INTERRURT 不重啟。SA_RESTART重啟。
擴展了解:
sa_flags還有許多可選參數,適用不同情況,如:捕捉到信號后,在執行捕捉函數期間,不希望屏蔽該信號,可將sa_flags設置為SA_NODEFER,除非sa_mask中包含該信號。
?
1. 測試代碼:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdbool.h> #include <signal.h> #include <sys/types.h> #include <errno.h> #include <string.h>void int_handler(int signum) {printf("int handler %d\n", signum); }int main(int argc, char **argv) {char buf[100];ssize_t ret;struct sigaction oldact;struct sigaction act;act.sa_handler = int_handler;act.sa_flags = 0;act.sa_flags |= SA_RESTART;sigemptyset(&act.sa_mask);if (-1 == sigaction(SIGINT, &act, &oldact)) {printf("sigaction failed!\n");return -1;}bzero(buf, 100);ret = read(STDIN_FILENO, buf, 10);if (ret == -1) {printf("read error %s\n", strerror(errno));}printf("read %d bytes, content is %s\n", (int)ret, buf);sleep(10);return 0; }輸出結果:
?
?
2. 測試代碼:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdbool.h> #include <signal.h> #include <sys/types.h> #include <errno.h> #include <string.h>void int_handler(int signum) {printf("int handler %d\n", signum); }int main(int argc, char **argv) {char buf[100];ssize_t ret;struct sigaction oldact;struct sigaction act;act.sa_handler = int_handler;act.sa_flags = 0;// act.sa_flags |= SA_RESTART;sigemptyset(&act.sa_mask);if (-1 == sigaction(SIGINT, &act, &oldact)) {printf("sigaction failed!\n");return -1;}bzero(buf, 100);ret = read(STDIN_FILENO, buf, 10);if (ret == -1) {printf("read error %s\n", strerror(errno));}printf("read %d bytes, content is %s\n", (int)ret, buf);sleep(10);return 0; }輸出結果:
?
參考資料
1.?linux SA_RESTART的問題
2.?44-中斷系統調用與自動重啟動
總結
- 上一篇: 怎样用jquery生成带有倾斜角度的验证
- 下一篇: lol法师需要哪些符文,想要一套经济实用