国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

Linux被中斷的系統如何調用詳解

2024-08-28 00:02:10
字體:
來源:轉載
供稿:網友

前言

慢系統調用,指的是可能永遠無法返回,從而使進程永遠阻塞的系統調用,比如無客戶連接時的accept、無輸入時的read都屬于慢速系統調用。

在Linux中,當阻塞于某個慢系統調用的進程捕獲一個信號,則該系統調用就會被中斷,轉而執行信號處理函數,這就是被中斷的系統調用。

然而,當信號處理函數返回時,有可能發生以下的情況:

如果信號處理函數是用signal注冊的,系統調用會自動重啟,函數不會返回 如果信號處理函數是用sigaction注冊的 默認情況下,系統調用不會自動重啟,函數將返回失敗,同時errno被置為EINTR 只有中斷信號的SA_RESTART標志有效時,系統調用才會自動重啟

下面我們編寫代碼,分別驗證上述幾種情形,其中系統調用選擇read,中斷信號選擇SIGALRM,中斷信號由alarm產生。

使用signal

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <errno.h>void handler(int s){  printf("read is interrupt by signal handler/n");  return;}int main(){  char buf[10];  int nread = 0;  signal(SIGALRM, handler);  alarm(2);  printf("read start/n");  nread = read(STDIN_FILENO, buf, sizeof(buf));  printf("read return/n");  if ((nread < 0) && (errno == EINTR))  {    printf("read return failed, errno is EINTR/n");  }  return 0;}

使用sigaction + 默認情況

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <errno.h>void handler(int s){  printf("read is interrupt by signal handler/n");  return;}int main(){  char buf[10];  int nread = 0;  struct sigaction act;  sigemptyset(&act.sa_mask);  act.sa_handler = handler;  act.sa_flags = 0; //不給SIGALRM信號設置SA_RESTART標志,使用sigaction的默認處理方式  //act.sa_flag |= SA_INTERRUPT; //SA_INTERRUPT是sigaction的默認處理方式,即不自動重啟被中斷的系統調用  //實際上,不管act.sa_flags值為多少,只要不設置SA_RESTART,sigaction都是按SA_INTERRUPT處理的  sigaction(SIGALRM, &act, NULL);  alarm(2);  printf("read start/n");  nread = read(STDIN_FILENO, buf, sizeof(buf));  printf("read return/n");  if ((nread < 0) && (errno == EINTR))  {    printf("read return failed, errno is EINTR/n");  }  return 0;}


使用sigaction + 指定SA_RESTART標志

#include <stdio.h>#include <signal.h>#include <unistd.h>#include <errno.h>void handler(int s){  printf("read is interrupt by signal handler/n");  return;}int main(){  char buf[10];  int nread = 0;  struct sigaction act;  sigemptyset(&act.sa_mask);  act.sa_handler = handler;  act.sa_flags = 0;  act.sa_flags |= SA_RESTART; //給SIGALRM信號設置SA_RESTART標志  sigaction(SIGALRM, &act, NULL);  alarm(2);  printf("read start/n");  nread = read(STDIN_FILENO, buf, sizeof(buf));  printf("read return/n");  if ((nread < 0) && (errno == EINTR))  {    printf("read return failed, errno is EINTR/n");  }  return 0;}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 怀仁县| 揭西县| 肥东县| 乐清市| 韩城市| 金川县| 郸城县| 秭归县| 乌兰浩特市| 江孜县| 阳山县| 民乐县| 霸州市| 望奎县| 日土县| 景东| 九龙城区| 武夷山市| 竹溪县| 靖江市| 鲁甸县| 壶关县| 阿荣旗| 榆树市| 砚山县| 黔南| 章丘市| 东城区| 响水县| 瓮安县| 灵璧县| 长沙县| 富川| 荣成市| 彭州市| 宁陕县| 汉川市| 吴堡县| 蛟河市| 赤峰市| 乌拉特中旗|