1. 程式人生 > >UNP卷一學習筆記:I/O模型

UNP卷一學習筆記:I/O模型

UNIX下可用的5種I/0模型:

(1)阻塞式I/O   (2)非阻塞式I/O   (3)I/O複用   (4)訊號驅動I/O(SIGIO)    (5)非同步I/O

前4種屬於同步操作,第5種屬於非同步操作。

下面以釣魚(套接字輸入操作)為例說明這5種模型:

完成釣魚需要兩步驟:

完成套接字輸入需要兩步驟:

a.等待魚上鉤   

a.等待資料準備好

b.釣起魚放入桶內 

b.從核心向程序複製資料

                 

(1)阻塞式I/O                              

小明拿著魚竿等待魚上鉤,上鉤前小明除了一直盯著浮標,不做任何事,魚上鉤後將魚釣起放入桶內。

(2)非阻塞I/O

小明拿著魚竿等待魚上鉤,上鉤前小明低著頭玩手機,每隔一段時間擡頭看浮標,若魚上鉤就將其釣起放入桶內,若沒有則又低頭玩手機,每隔一段時間擡頭看浮標,直到魚上鉤。

(3)I/O複用

小明嫌一根魚竿釣魚不過癮,於是帶了好幾根魚竿去釣魚。他將這些魚竿的線都丟擲,並用工具固定好魚竿,然後等著魚上鉤,一有魚竿魚上鉤,就釣起魚放入桶內。

(4)訊號驅動式I/O

小明帶了女友小紅一塊去釣魚,他讓小紅守著魚竿而且一有魚就叫他,自己卻跑樹下玩手機,魚上鉤後,小紅叫了小明,小明過去釣起魚放入桶內。

(5)非同步I/O

這次小明為了鍛鍊小紅的技術,讓小紅自己一人守著魚竿,魚上鉤了也讓小紅自己釣起放入桶內,小明自己一直坐旁邊玩手機。

select函式允許程序指示核心等待多個事件中的任何一個發生,並只在有一個或多個事件發生或經歷一段指定的時間後才喚醒它。

#include<sys/select.h>
#include<sys/time.h>
int select(int maxfdp1,fd_set*readset,fd_set* writeset,fd_set* exceptset,\
const struct timeval*timeout);
//返回:若有就緒描述符則為其數目,若超時則為0,若出錯則為-1

struct timeval{
  long tv_sec;     //秒
  long tv_usec;    //微妙
}

timeout設定:

a.永遠等帶下去:僅在任意一個描述符準備好I/O時才返回。

b.等待一段固定時間:在任意一個描述符準備I/O時返回,但是不能超過由該引數指定的時間。

c.根本不等待:檢查描述符後立即返回,這稱為輪詢。timeout中的值均設為0。

fd_set是一個描述符集,通常是一個整數陣列,其中每個整數中的每一位對應一個描述符。引數readset、writeset、excepetset分別是讓核心測試的讀、寫和異常條件描述符。描述符開啟狀態置1,關閉狀態置0。select返回後,開啟的描述符狀態會變為0。

引數maxfdp1指定待測試的描述符個數,描述符從0開始,最大描述數量FD_SETSIZE一般為1024。

描述符就緒條件:

條件

可讀

可寫

異常

有資料可讀(read,recv)

傳送方傳送FIN

監聽套接字準備好新連線(accept)

有空間可寫(write,send)

寫程序關閉

套接字產生待處理錯誤

TCP帶外資料

select函式的缺點:

(1)select的最大描述符數受限制,預設為FD_SETSIZE=1024,對於高併發的伺服器來說這個數量明顯不夠,如果想要修改這個上限,不得不對整個unp相關的檔案進行重新編譯。

(2)在呼叫select函式時,需要把三個讀、寫、異常的fd_set集合往核心拷貝,這會引起很大的開銷。

(3)在核心中select函式需要不斷輪詢所有的fd_set集中的描述符,以此來確定就緒的描述符,這也會引起很大開銷。

(在同一時刻,如果只有很少一部分描述符就緒,select函式的效率就會因為整個描述符的數量增加而線性下降)

epoll系列函式:

int epoll_create(int size);//設定可以管理的描述符數量上限,並返回管理它們的描述符
int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);
//為epfd中的描述符fd編輯(op:註冊,修改,刪除)要核心監聽的事件event
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
//等待事件的產生,類似於select()呼叫。成功返回:就緒的事件數目,超時返回0

相比於select函式,epoll系列函式的優點

(1)允許使用者自己設定描述符數目的上限,而且這個上限可以遠遠大於FD_SETSIZE。

(2)epoll_wait函式不需要去輪詢所有監聽的描述符,當某一描述符就緒時,核心會通過回撥機制,將就緒的描述符插入佇列中,epoll_wait函式只需判斷該佇列是否為空就行,不用遍歷整個描述符集合,這樣大大減少了系統開銷。

(3)無論是select函式還是epoll都需要將描述符集合從使用者空間拷貝到核心中,等描述符就緒又要將事件從核心空間拷貝到使用者空間,epoll採用了mmap加速核心與使用者空間的訊息傳遞,mmap是核心與使用者空間共用的一塊記憶體,因此可以避免不必要的記憶體拷貝。

shutdown函式:

#include<sys/socket.h>
int shutdown(int sockfd,int howto);
//返回:若成功返回0,出錯則返回-1;

howto引數:

a.SHUT_RD(0):關閉連線的讀這一半——套接字中不再有資料可接收,而且套接字接收緩衝區中的現有資料都被丟棄。

b.SHUT_WR(1):關閉連線的這一半——當前留在套接字傳送緩衝區中的資料都被髮送掉,後跟TCP的正常連線終止序列。

c.SHUT_RDWR(2):關閉的連線的讀寫兩半——等價於第一次呼叫SHUT_RD,第二次呼叫SHUT_WR。

shutdown 與 close的區別:

(1)close把描述符引用計數減一,僅在該計數變為0時才關閉套接字;shutdown可以不管引用計數就激發TCP的正常連線終止序列。

(2)close終止TCP雙方的讀寫資料傳送(四次揮手),shutdown允許只關閉一方。

相關推薦

UNP學習筆記I/O模型

UNIX下可用的5種I/0模型: (1)阻塞式I/O   (2)非阻塞式I/O   (3)I/O複用   (4)訊號驅動I/O(SIGIO)    (5)非同步I/O 前4種屬於同步操作,第5種屬於非

作業系統學習筆記I/O輸入系統

計算機兩大主要任務:IO操作和計算處理。許多情況下,主要是IO操作,計算處理只是附帶的(而作業系統的兩大任務是管理物理裝置和為應用程式提供一個虛擬機器器的抽象)。作業系統在IO方面的作用是管理IO操作和IO裝置。 一、概述 I/O裝置在功能與速度方面存在很大

筆記I/O流-字符集

表示 ava deb 建立 gin integer 示例 字節 標準化 Java 庫的 java.nio 包用 Charset 類統一了對字符集的轉換,支付姐建立了兩個字節Unicode碼元序列與使用本地字符編碼方式的字節序列之間的映

筆記I/O流-對象序列化

err extends 自己 point clas xtend his size cto Java 語言支持一種稱為對象序列化(Object Serialization)的非常通用的機制,可以將任何對象寫入到流中,並在之後將其讀回,首先需要支持對象

筆記I/O流-內存映射文件

pos 開始 col java mod 傳播 寫入 i/o .get 內存映射文件時利用虛擬內存實現來將一個文件或者文件的一部分映射到內存中,然後整個文件就可以當作數組一樣的訪問,這個比傳統的文件操作要快得多,Java 使用內存映射文件首先需要從文件中獲取一個cha

Java筆記I/O

out eno display cat java筆記 txt fileinput put one 一、流 Java通過流實現I/O,流是一種可以產生或使用信息的抽象。 Java定義了兩種類型的流: 字節流:處理字節的輸入和輸出,例如讀寫二進制數據。 字符流:處理字符的輸入

《Java程式設計思想》學習筆記14——I/O高階

1.記憶體對映檔案: 記憶體對映檔案允許把比記憶體大的檔案讀入記憶體中建立和修改,使用記憶體對映檔案,可以像使用記憶體中陣列一樣在記憶體中訪問整個檔案,例子如下: import java.nio.*;   import java.nio.channels.*;  

Java NIO學習系列五I/O模型

  前面總結了很多IO、NIO相關的基礎知識點,還總結了IO和NIO之間的區別及各自適用場景,本文會從另一個視角來學習一下IO,即IO模型。什麼是IO模型?對於不同人、在不同場景下給出的答案是不同的,所以先限定一下本文的上下文:Linux環境下的network IO。   本文會從如下幾個方面展開:   

Linux網路程式設計(5)I/O模型

       這一部分的內容本來應該作為第四部分內容,置於上一講之中的。由於當時自己學習時也存在很大的困惑,邊學邊用,因此造成了知識體系的不連貫性。我們開始學習吧。 (1)什麼是I/O複用(I/O multiplexing)呢?         當你編寫的程式需要同時處理多

caffe學習筆記caffe網路模型檔案(.prototxt)layer與layers區別

編寫caffe網路模型檔案的時,有layer與layers兩種方式,其不同之處主要在於網路型別type的定義方式不同,例如定義type為hdf5資料型別時,其定義方式如下。1. 使用layerlayer {  name: "data"  type: "HDF5Data"  t

作業系統的永續性學習I/O Devices

最近由於專案需要,需要學習相關的檔案系統,覺得當時在學習作業系統的時候對檔案系統方向的知識比較匱乏,所以特地來進行補充知識。 I/O匯流排 在介紹I/O裝置的時候,我們要先知道我們的device(HDD,SDD)是如何接到我們的CPU上的,下面來放一個相關的I/

Python學習筆記變數與簡單I/O

變數(variable):用於引用(繫結)物件的識別符號。增量賦值運算子:累加:count=count+1 或者 count +=1識別符號(identifier)有其命名規則。標準(鍵盤)輸入:input標準(控制檯)輸出:print

《TCP/IP詳解2實現》筆記--插口I/O

本文介紹有關網路連線上讀寫資料的系統呼叫,分三部分: 第一部分介紹四個用來發送資料的系統呼叫:write,writev,sendto和sendmsg。第二部分介紹四個用來接收資料的系統 呼叫:read、readv、recvfrom和recvmsg。第三部分介紹select系

git學習筆記臺電腦上配置兩個git賬戶

idt ica 項目 auth 開源中國 重復 gmail name 微軟 如何在一臺電腦上配置兩個git賬戶,現在雲端倉庫很多,有開源中國的 gitee.com 微軟的 github.com 還有 gitlab.com 和 bitbucket.org 等等,下面是具體步驟

effectiveJava學習筆記通用程式設計()

將區域性變數的作用域最小化 其實大部分人還是在第一次使用變數的時候宣告變數的,在開頭就將所有變數宣告的還沒見過。 要使區域性變數的作用域最小化,最有力的方法就是在第一次使用它的地方宣告。 但是,這裡書中講到了for迴圈優於while迴圈,值得我們注意。 for迴圈將變數宣告在迴圈內,

effectiveJava學習筆記方法()

檢查引數的有效性 1、一般在方法執行之前先檢查引數的有效性,如果引數值無效,那麼很快它就會失敗,並且清楚的丟擲合適的異常。 如果這個方法沒有檢查引數的異常,那麼可能在方法處理中出現令人費解的異常。更糟糕的有可能是,方法可以正常返回,但是卻使得某個物件處於被破壞的狀態. 2、對於公有方法,

effectiveJava學習筆記泛型()

先給大家列出需要的術語 在新程式碼中(jdk1.5以後)不要使用原生態的型別。 為什麼會有泛型 list<E> 如果沒有泛型的話,我們從一個沒有定義型別的集合裡面取資料的時候就不知道是什麼型別,強制轉換會出現ClassCastException異常 這時候原生態型別

effectiveJava學習筆記類和介面()

一、使類和成員的可訪問性最小化 對於類 對於類,只有public和package-private兩種訪問級別。package-private是預設的,也就是預設的。 1.對於頂層的類來說,只有包級私有和公有兩種可能,區別是包級私有意味著只能在當前包中使用,不會成為匯出api的一部分,而公

《Java 核心技術Ⅰ》—學習筆記2

  第四章 物件和類 (網路資料https://blog.csdn.net/world_snow/article/details/78831127) 物件:物件就是一個真實世界中的實體,物件與實體是一一對應關係的,意思就是現實世界的每一個實體都是一個物件,所以物件是一個具體的概念。 類: 具

python核心程式設計第三版(學習筆記正則表示式

注:下面有些內容不全都來源於原著,這些都是通過各方面的資料收集合並的結果。 目錄 1、元字元 3、邊界詞 4、分組詞 一、正則表示式介紹 正則表示式為高階的文字模式匹配、抽取、與/或文字形式的搜尋和替換功