I/O會一直佔用CPU嗎?

阻塞io情況下,比如磁碟io,accept ,read,recv,write等調用導致進程或者線程阻塞,這時候線程/進程 會佔用cpu嗎?比如連接mysql,執行一條需要執行很長的sql語句,recv調用的時候阻塞了,這個時候會不會大量佔用cpu時間?磁碟io是什麼操作,比如linux調用cp拷貝大文件的時候會大量佔用cpu嗎?


這是一個很好的關於並發/並行系統的問題。簡單回答就是:IO所需要的CPU資源非常少。大部分工作是分派給DMA完成的。

先不談傳統的5大IO模型,先說說並發(Concurrence)。一個非常不嚴謹的解釋就是同時做A和B兩件事。先做一會兒進程A,然後上下文切換,再做一會兒B。過一會兒在切回來繼續做A。因此給我們造成一個假象,我們同時在做A和B兩件事。這就是著名的進程模型。

這看上去很炫酷,但實際上並沒有任何卵用。因為A,B兩件事你都得做完不是?不論你是做完A再做B還是來回切換,花得時間應該是一樣的。甚至還要更多,因為還要考慮到上下文切換的開銷。所以我第一次學到並發進程模型的時候,心裡是一萬個白眼。

但是,如果計算機內部不止CPU一個部件在工作呢?如果A這件事CPU可以分派給其他部件幫它完成呢?情況是不是就完全不一樣了?系統IO正好是這樣一個完美的例子。

對於磁碟IO,真實發生的場景可能是這樣的:

CPU說:硬碟兄幫我把我要看的小電影拷貝一份到主存,謝謝,親。

硬碟說:好的!我考完了叫你。

CPU說:么么噠!那我打遊戲去啦!

...

CPU打擼啊擼 (100納秒過去了)

...

硬碟說:小C我考完了。

CPU說:蒼老師我來啦!

當然我們也可以到網上下載蒼老師的作品,這就是網路IO。但情況基本是一樣的,CPU童鞋在等小電影的過程中,打了一局擼啊擼。

所以,正因為這樣派發任務,通訊,等待的過程,並發系統才彰顯出它的意義。當然實際過程可能比這個複雜一萬倍。比如CPU是不會直接和硬碟對話的,他們之間有個中間人,叫DMA(Direct Memory Access)晶元.

CPU計算文件地址 Rightarrow 委派DMA讀取文件 Rightarrow DMA接管匯流排 Rightarrow CPU的A進程阻塞,掛起 Rightarrow CPU切換到B進程 Rightarrow DMA讀完文件後通知CPU(一個中斷異常) Rightarrow CPU切換回A進程操作文件

這個過程,對應下圖(圖源:《UNIX網路編程》),看到application這一列時間線了嗎?aio_read操作之後,都是空白,CPU就不管了,可以做其他事去了。

假設原先讀取文件CPU需要傻等50納秒。現在儘管兩次上下文切換要各消耗5納秒。CPU還是賺了40納秒時間片。一看上面這張圖就知道,剛才講的是傳統5大IO模型中的「非同步IO」的大致過程。想進一步了解,推薦直接讀《UNIX網路編程》第一冊套接字,經典哦!


計算機硬體上使用DMA來訪問磁碟等IO,也就是請求發出後,CPU就不再管了,直到DMA處理器完成任務,再通過中斷告訴CPU完成了。所以,單獨的一個IO時間,對CPU的佔用是很少的,阻塞了就更不會佔用CPU了,因為程序都不繼續運行了,CPU時間交給其它線程和進程了。雖然IO不會佔用大量的CPU時間,但是非常頻繁的IO還是會非常浪費CPU時間的,所以面對大量IO的任務,有時候是需要演算法來合併IO,或者通過cache來緩解IO壓力的。


可以占也可以不佔,可以占的多,也可以占的少,以前占的多,現在占的少。我先佔坑,以後作答。


你知道IO的五種方式嗎?

程序直接控制

中斷

DMA

外圍處理機

通道

我如果背錯了不要打我(*/ω\*)


你聽說過一種東西叫做多隊列網卡嘛?

在一般的網卡中,都有且僅有一個隊列——從網路來的數據包存在這個隊列當中,一旦隊列符合一定條件,將觸發軟中斷,調用CPU去處理數據包。DMA什麼的是用來將數據放到內存裡面的,但是中斷仍然是必須的。

在某些情況下,網卡隊列滿了,為了防止出錯,就必須調用CPU儘快來處理網卡隊列……在多CPU的情況下,你以為會多個CPU分擔對隊列的處理么?

少年不要too young啊~事實上,在linux中是綁定一個CPU到網卡隊列的。這樣,就導致了:

明明其他CPU還20%-30%,但是整機處理速度就是上不去,仔細一看:我擦,某個CPU100%,而網卡隊列已滿。

由於鎖機制的蛋疼,你重新寫個驅動讓多個CPU去處理隊列得不償失。

以上。


其他答主都說了linux, 在windows上,不要說佔用CPU, 連線程都不需要。傳送門:There Is No Thread


首先IO是非常慢的,如果一直佔用cup,那cpu不用干別的了。

你可能會說,那我劃分時間片佔用cpu啊,問題來了,這麼長時間的任務一直在cpu放著,其他任務分配的時間片不就少了嗎。

所以現代計算機一般採用通道處理機,通道處理機是什麼呢。它是一個獨立於cpu的外圍設備,自己就有少量的存儲空間,可以獨立完成輸入輸出操作。

通道處理機完成了cpu指定的I/O操作,返回一個I/O中斷。

當然了DMA和外圍處理機也是完成I/O的方式,當然還有純I/O程序控制。


阻塞io情況下,比如磁碟io,accept ,read,recv,write等調用導致進程或者線程阻塞,這時候線程/進程 會佔用cpu嗎?

對於阻塞IO

如果因為沒有數據調用read()/recv() ,此時通常是不佔用CPU的;這些read()/recv() 實現中,通常是在等待時調用了調度介面,讓出了CPU(進程從可運行狀態轉移到掛起狀態)。

使用阻塞IO 介面做磁碟IO,這個? 如何阻塞呢?read() 在文件指針到達文件末尾,沒有數據的情況下會立即返回;如果是因為系統有大量的read()動作導致的阻塞的確會導致CPU使用率上升;write()在page cache 滿的情況下的確會阻塞,此時可能系統正在做flush 動作:讓page cache 和文件系統(通常是外存,也可能是網路設備)同步,此時CPU 的使用率的確會上升;

如果是因為出現了大量的read()/write(),即使外存控制器使用的是DMA模式那麼CPU使用率肯定會上去,如果使用PIO模式的話,CPU的使用率會飆的更高。

關於cp 命令,如果是regular 文件,無非是

fd_src = open(src, ...);

fd_dst = open(dst, ...);

之後循環

read(fd_src,buf,xxx)

write(fd_dst,buf,xxx)

對於當前主流的硬體配置,這個動作不會太佔用CPU,因為硬體通常不會太快(尤其是使用HDD的情況下)。

具體可以在機器上面試一試,可以使用top 命令查看。


"IO所需要的CPU資源非常少"---過於理想化了,IO阻塞容易發生,例如光碟機讀差光碟,經常導致圖面界面的應用卡頓。


推薦閱讀:

gnome2.x 和 gnome3 哪個更好?
如何給ARM-linux移植桌面系統?哪款桌面系統適合入門移植?
發現自己有系統和軟體升級強迫症怎麼辦?
你什麼時候對 ubuntu 感到絕望?
用到了高版本Qt庫,但Ubuntu更新不到那麼高的Qt版本,自己拷貝高版本Qt庫過去又有問題,怎麼辦?

TAG:操作系統 | 中央處理器CPU | Linux | 計算機網路 |