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

首頁 > 學院 > 操作系統 > 正文

高級I/O之非阻塞I/O

2024-06-28 13:28:05
字體:
來源:轉載
供稿:網友
高級I/O之非阻塞I/O

http://www.CUOXin.com/nufangrensheng/p/3515035.html中曾將系統調用分成“低速”系統調用和其他系統調用兩類。低速系統調用是可能會使進程永遠阻塞的一類系統調用,它們包括下列調用:

  • 如果某些文件類型(例如管道、終端設備和網絡設備)的數據并不存在,則讀操作可能會使調用者永遠阻塞。
  • 如果數據不能立即被上述同樣類型的文件接受(由于在管道中無空間、網絡流控制等),則寫操作也會使調用者永遠阻塞。
  • 在某種條件發生之前,打開某些類型的文件會被阻塞(例如打開一個終端設備可能需等到與之連接的調制解調器應答;又例如在沒有其他進程已用讀模式打開該FIFO時,若以只寫模式打開FIFO,那么也要等待)。
  • 對已經加上強制性記錄鎖的文件進行讀、寫。
  • 某些ioctl操作。
  • 某些進程間通信函數。

雖然讀、寫磁盤文件會使調用者在短暫時間內阻塞,但并不能將與磁盤I/O有關的系統調用視為“低速”。

非阻塞I/O使我們可以調用open、read和write這樣的I/O操作,并使這些操作不會永遠阻塞。如果這種操作不能完成,則調用立即出錯返回,表示該操作如繼續執行將阻塞。

對于一個給定的描述符有兩種方法對其指定非阻塞I/O:

(1)如果調用open獲得描述符,則可指定O_NONBLOCK標志(http://www.CUOXin.com/nufangrensheng/p/3497789.html)。

(2)對于已經打開的一個描述符,則可調用fcntl,由該函數打開O_NONBLOCK文件狀態標志(http://www.CUOXin.com/nufangrensheng/p/3500350.html,其中,程序清單3-5中的函數可用來為一個描述符打開任一文件狀態標志)。

系統V的早期版本使用標志O_NDELAY指定非阻塞方式。在這些版本中,如果無數據可讀,則read返回值0。而UNIX系統又常將read返回值0解釋為文件結束,兩者有所混淆。因此POSIX.1提供了一個名字和語義都與O_NDELAY不同的非阻塞標志。確實,在系統V的早期版本中,當從read得到返回值0時,我們并不知道該調用是否阻塞了或已到文件結尾處。POSIX.1要求,對于一個非阻塞的描述符如果無數據可讀,則read返回-1,并且errno被設置為EAGAIN。系統V派生的某些平臺支持較老的O_NDELAY和POSIX.1的O_NONBLOCK兩者。O_NDELAY只是為了向后兼容,不應在新應用程序中使用。

4.3BSD為fcntl提供了FNDELAY標志,其語義也稍有區別。它不只影響描述符的文件狀態標志,還將終端設備或套接字的標志更改成非阻塞的,因此不僅影響共享同一文件表項的用戶,而且對終端或套接字的所有用戶其作用。另外,如果對一個非阻塞描述符的操作不能無阻塞地完成,那么4.3BSD返回EWOULDBLOCK。現今,基于BSD的系統提供POSIX.1的O_NONBLOCK標志,并且將EWOULDBLOCK定義為與POSIX.1的EAGAIN相同。這些系統提供與其他依從POSIX系統相一致的非阻塞語義。文件狀態標志的更改影響同一文件表項的所有用戶,但與通過其他文件表項對同一設備的訪問無關(參加圖3-1http://www.CUOXin.com/nufangrensheng/p/3498509.html和圖3-3http://www.CUOXin.com/nufangrensheng/p/3498736.html)。

實例

程序清單14-1是一個非阻塞I/O的實例,它從標準輸入讀500 000字節,并試圖將它們寫到標準輸出上。該程序先將標準輸出設置為非阻塞的,然后用for循環進行輸出,每次write調用的結果都在標準出錯上打印。函數clr-fl類似于程序清單3-5(http://www.CUOXin.com/nufangrensheng/p/3500350.html)中的set_fl,但與set_fl的功能相反,它清除1個或多個標志位。

程序清單14-1 長的非阻塞write

#include "apue.h"#include <errno.h>#include <fcntl.h>char     buf[500000];extern void set_fl(int, int);extern void clr_fl(int, int);intmain(void){    int    ntowrite, nwrite;    char    *ptr;    ntowrite = read(STDIN_FILENO, buf, sizeof(buf));    fPRintf(stderr, "read %d bytes/n", ntowrite);    set_fl(STDOUT_FILENO, O_NONBLOCK);    /* set nonblocking */    ptr = buf;    while(ntowrite > 0)                   /* 這種形式的循環稱為輪循,在多用戶系統上它浪費了CPU時間。*/    {        errno = 0;        nwrite = write(STDOUT_FILENO, ptr, ntowrite);        fprintf(stderr, "nwrite = %d, errno = %d/n", nwrite, errno);        if(nwrite > 0)        {            ptr += nwrite;            ntowrite -= nwrite;        }    }    clr_fl(STDOUT_FILENO, O_NONBLOCK);    /* clear nonblocking */    exit(0);}

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 沅江市| 略阳县| 淮滨县| 宁夏| 宜丰县| 九寨沟县| 久治县| 潮安县| 虹口区| 双峰县| 荔波县| 鹿泉市| 隆尧县| 昂仁县| 博湖县| 西林县| 马山县| 鄱阳县| 铅山县| 奉节县| 淮北市| 朝阳区| 惠东县| 吐鲁番市| 双流县| 聂荣县| 兴隆县| 德格县| 金阳县| 普陀区| 南丹县| 天长市| 石阡县| 昌宁县| 陇南市| 韶关市| 武川县| 仁怀市| 洱源县| 孝义市| 龙游县|