就好比,你買東西,付過錢以後,你可以:
等著東西做好:同步(主動獲得結果)
做其他的。等著老闆做好了喊我:非同步(被動獲得結果)
再比如:使用者程式從核心讀取資料,如果核心快取中資料還沒有準備好,如果是同步操作,程序觸發io操作,一直等待或者輪詢的去檢視io操作是否完成(這個步驟不執行結束,接下來的事情都不能做)。如果是非同步操作,那麼它會去做別的事情,程序觸發io操作以後,直接返回,做自己的事情,io操作交給核心來處理,等待資料準備好,核心通知它,使用者程式再去讀取資料。
同步和非同步是相對於操作結果來說,區別在於會不會等待結果返回。
兩者之間的區別: 我的理解是這樣的:在於使用者程序是否將所有io操作交給cpu去完成。若交給cpu之後就可以什麼都不用管,只需要等待通知就可以了,那麼就是非同步(等通知,然後read);如果需要等待io操作的完成,沒有將io操作的權利全都託付給cpu的為同步(eg:一直read(任務佇列,阻塞),一會read一下(輪詢,非阻塞))。
1.2.1 非同步通知的核心:發訊號
阻塞:無資料準備好,系統呼叫比如read就會掛起,等到有資料準備好或者有資料了才繼續執行系統呼叫,最後才從系統呼叫的函式中返回。
非阻塞: 沒有資料,就立刻返回
可將poll機制和這個聯絡起來:
如果poll的超時時間0,就是非阻塞;
如果poll的超時時間!=0;就是阻塞。阻塞的時間poll的超時時間。
非同步操作是可以被阻塞住的,只不過它不是在處理訊息時阻塞(第二步驟),而是在等待訊息通知時被阻塞(第一步驟)。
所以,從這個角度,可以進行區分:
阻塞io和非阻塞io的區別就在於:應用程式的呼叫是否立即返回!也就是在(等待資料)這一步驟進行區分的。
同步io和非同步io的區別就在於:資料拷貝的時候程序是否阻塞!也就是從資料從核心拷貝到使用者空間這一步來進行區分的。
如果要是按照這麼分類的話,非同步是真正意義上的非阻塞,所以非同步不分阻塞和非阻塞,只有同步才分阻塞和非阻塞。
int flags =
fcntl
(fd, f_getfl)
;fcntl
(fd, f_setfl, flags | o_nonblock)
;/* 非阻塞方式 */
fcntl
(fd, f_setfl, flags &
~o_nonblock)
;/* 阻塞方式 */
注:上述兩種方法,最終都會給filp結構體中的flag賦值(上一節的非同步通知的開啟和關閉也是通過flag中的一位fasync進行判斷的)。file *filp結構體由核心檔案系統自動建立,給核心使用
3、驅動程式的處理
static ssize_t drv_read
(struct file *fp,
char __user *buf, size_t count, loff_t *ppos){if
(queue_empty
(&as->queue)
&& fp->f_flags & o_nonblock)
return
-eagain;
wait_event_interruptible
(apm_waitqueue,
!queue_empty
(&as->queue));
……}
阻塞,非阻塞,非同步,同步
之前一直對這個概念理不太清楚,今天看到一篇文章感覺不錯 本文 老張愛喝茶,廢話不說,煮開水。出場人物 老張,水壺兩把 普通 水壺,簡稱水壺 會響的水壺,簡稱響水壺 1 老張把水壺放到火上,立等水開。同步阻塞 老張覺得自己有點傻 2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。同步非阻...
同步 非同步 阻塞 非阻塞
故事 老王燒開水。出場人物 老張,水壺兩把 普通水壺,簡稱水壺 會響的水壺,簡稱響水壺 老王想了想,有好幾種等待方式 1.老王用水壺煮水,並且站在那裡,不管水開沒開,每隔一定時間看看水開了沒。同步阻塞 老王想了想,這種方法不夠聰明。2.老王還是用水壺煮水,不再傻傻的站在那裡看水開,跑去寢室上網,但是...
同步 非同步 阻塞 非阻塞
故事 老王燒開水。出場人物 老張,水壺兩把 普通水壺,簡稱水壺 會響的水壺,簡稱響水壺 老王想了想,有好幾種等待方式 1.老王用水壺煮水,並且站在那裡,不管水開沒開,每隔一定時間看看水開了沒。同步阻塞 老王想了想,這種方法不夠聰明。2.老王還是用水壺煮水,不再傻傻的站在那裡看水開,跑去寢室上網,但是...