1.I/O
兩個相鄰存儲級別之間的數據傳輸,統稱 I/O 操做(好比內存與外存,同級的不需 I/O 操做)各級存儲器的訪問速度相差懸殊,故應儘量地減小 I/O 操做。仍之內存和磁盤爲例,其單次訪問延遲大體分別在納秒(ns)和毫秒(ms)級別,相差 5 至 6 個數量級。形象地說來,就是對內存而言的 一秒/一天,至關於磁盤的 一週/兩千年。算法
所以,爲減小對外存的一次訪問,咱們寧願訪問內存百次,千次甚至萬次。也正因如此,在衡量相關算法的性能時,基本能夠忽略對內存的訪問,轉而更多地關注對外存的訪問次數segmentfault
比較常見的IO,disk IO, net IO, std IO,等數組
2.進程和線程的區別
對每個運行的應用即進程,在內存中都有本身的一塊獨立的空間,不一樣進程間相互隔離,在一個進程中至少有一個線程,在只有一個cpu的狀況下,一個進程的多個線程間分時利用CPU執行任務,多個線程共享進程的資源,多個CPU狀況下,進程的多個線程間能夠真正的併發執行。當一個進程執行完畢或分配的CPU時間片用完的時候,會將進程上下文保存,而後取出另外一個進程的上下文,執行該進程,而後保存上下文,繼續執行下一個...
進程是資源分配的最小單位,線程是CPU調度的最小單位
進程切換比線程切換更耗資源,不一樣進程間切換須要保存上一個進程的上下文,加載下一個進程的上下文,這中間會消耗更多的資源(Java裏線程好像也是要切換的)
線程粒度更小,線程是存在於進程中的,不存在獨立於進程以外的線程,一個進程至少有一個線程,叫主線程
進程是靜態的線是動態的,進程就是全了一塊地存儲資源,真正CPU運行執行任務是線程裏面實現的。
知乎上一個很好的理解角度bash
做者:zhonyong
連接:https://www.zhihu.com/question/25532384/answer/81152571
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
下面細說背景:CPU+RAM+各類資源(好比顯卡,光驅,鍵盤,GPS, 等等外設)構成咱們的電腦
,可是電腦的運行,實際就是CPU和相關寄存器以及RAM之間的事情。
一個最最基礎的事實
:CPU太快,太快,太快了,寄存器僅僅可以追的上他的腳步,RAM和別的掛在各總線上的
設備徹底是望其項背。那當多個任務要執行的時候怎麼辦呢?輪流着來?或者誰優先級高
誰來?無論怎麼樣的策略,一句話就是在CPU看來就是輪流着來。
一個必須知道的事實:
執行一段程序代碼,實現一個功能的過程介紹
,當獲得CPU的時候,相關的資源必須也已經就位,就是顯卡啊,GPS啊什麼的必須就位
,而後CPU開始執行。這裏除了CPU之外全部的就構成了這個程序的執行環境,也就是咱們
所定義的程序上下文。當這個程序執行完了,或者分配給他的CPU執行時間用完了,那它
就要被切換出去,等待下一次CPU的臨幸。在被切換出去的最後一步工做就是保存程序上
下文,由於這個是下次他被CPU臨幸的運行環境,必須保存。串聯起來的事實:前面講過在
CPU看來全部的任務都是一個一個的輪流執行的,具體的輪流方法就是:先加載程序A的上
下文,而後開始執行A,保存程序A的上下文,調入下一個要執行的程序B的程序上下文,
而後開始執行B,保存程序B的上下文。。。。=========
重要的東西出現了========進程和線程就是這樣的背景出來的,兩個名詞不過是對應的CP
U時間段的描述,名詞就是這樣的功能。進程就是包換上下文切換的程序執行時間總和 =
CPU加載上下文+CPU執行+CPU保存上下文線程是什麼呢?進程的顆粒度太大,每次都要有
上下的調入,保存,調出。若是咱們把進程比喻爲一個運行在電腦上的軟件,那麼一個軟
件的執行不多是一條邏輯執行的,一定有多個分支和多個程序段,就比如要實現程序A
,實際分紅 a,b,c等多個塊組合而成。那麼這裏具體的執行就可能變成:程序A獲得CPU
=》CPU加載上下文,開始執行程序A的a小段,而後執行A的b小段,而後再執行A的c小段,
最後CPU保存A的上下文。這裏a,b,c的執行是共享了A的上下文,CPU在執行的時候沒有
進行上下文切換的。這裏的a,b,c就是線程,也就是說線程是共享了進程的上下文環境
,的更爲細小的CPU時間段。到此全文結束,再一個總結:進程和線程都是一個時間段的
描述,是CPU工做時間段的描述,不過是顆粒大小不一樣。
複製代碼
3.select poll epoll
先介紹幾個概念網絡
文件描述符fd
文件描述符(File descriptor)是計算機科學中的一個術語,是一個用於表述指向文件的引用的抽象化概念。
文件描述符在形式上是一個非負整數。實際上,它是一個索引值,指向內核爲每個進程所維護的該進程打開文件的記錄表。當程序打開一個現有文件或者建立一個新文件時,內核向進程返回一個文件描述符。在程序設計中,一些涉及底層的程序編寫每每會圍繞着文件描述符展開。可是文件描述符這一律念每每只適用於UNIX、Linux這樣的操做系統。
複製代碼
什麼是I/O多路複用
IO multiplexing就是咱們說的select,poll,epoll,有些地方也稱這種IO方式爲event
driven IO。select/epoll的好處就在於單個process就能夠同時處理多個網絡鏈接的IO。
它的基本原理就是select,poll,epoll這些function會不斷的輪詢所負責的全部socket
,當某個socket有數據到達了,就通知用戶進程
I/O 多路複用的特色是經過一種機制一個進程能同時等待多個文件描述符,而這些文件描
述符(套接字描述符)其中的任意一個進入讀就緒狀態,select(),poll(),epoll()函數
再也不阻塞就能夠返回。
複製代碼
共同點併發
都是I/O多路複用,在一個進程中等待多個文件描述符,有任一個就緒,函數就中止阻塞
,函數返回,而後對就緒的文件描述符處理
複製代碼
不一樣點socket
對全部須要等待的文件描述符的數據封裝不一樣,對就緒的文件描述符尋找的方法不一樣有的
要遍歷有的不用,內核對文件描述符數據處理不一樣,有的會修改
複製代碼
select歷史最爲悠久,存在一些缺點ide
上圖是簡單的select源碼實現,上半部分是對多個文件描述符獲取,5個文件描述符都放在fds數組裏面,文件描述符大小不定,在1024之內,select第一個缺點就是單個進程監聽的文件描述符最大隻能是1024,因此fds數組裏面5個元素是0-1023的數,select函數第二個參數rset是bitmap結構,一共有1024位,每一位表明一個文件描述符,參數1中max是監聽的文件描述符中最大值,也就是告訴內核只須要看前max+1個位,後面的都用不到,select後面幾個參數分別是讀寫文件描述符和超時等信息,select須要將文件描述符集合從用戶空間拷貝到內核空間,有用戶態和空間態切換的資源消耗,這是第二個缺點,當有文件描述符就緒,內核會將rset中對應位置位,而後select函數返回,繼續執行下面的代碼,下面邏輯就是一次遍歷rset看哪個被置位,就處理哪個,這裏須要遍歷一邊才能找到就緒的文件描述符,複雜度是O(n),這是第三個缺點 缺點總結: 1.同一進程只能通知監聽1024個文件描述符 2.文件描述符合集須要從用戶空間拷貝到內核空間 3.須要遍歷一遍文件描述符合集才能找到就緒文件描述符函數
poll性能
epoll
epoll_create 至關於建立了一個空白塊,epfd,epoll_ctl至關於將文件描述符放進這個空白塊,將文件描述符和事件相對應,epoll經過內存映射將文件描述符合集放在用戶和內核共享空間,所以沒有用戶態內核態切換消耗,epoll_wait會等待文件描述符就緒,當有文件描述符就緒就會將全部的就緒的文件描述符往前排,而後返回就緒的文件描述符個數,返回後執行下面的代碼,就能夠不用遍歷全部的文件描述符,而後只處理前面的文件描述符,因此epoll解決了select,poll都沒有解決的問題 1.不須要將文件描述符合集拷貝到內核空間 2.不須要遍歷文件描述符合集找就緒文件描述符
因爲看了不少資料,每一個都有所簡化或者抽象歸納,底層原理講的有所差異,就像函數原型都不同,還有epoll如何實現不用遍歷,視頻是說重排,有的說是加中間層,鏈表,目前瞭解大概原理,具體暫定
上面截圖的視頻
好文章
好文章