天天看點

【高并發程式設計】再談同步、異步、阻塞、非阻塞

同步、異步、阻塞、非阻塞的概念一直是計算機學科中很重要的概念,而這種細微的差别常常被大家混淆,我自己在過一段時間後也需要複習。今天再次翻出這個概念,仍然覺得不夠清晰,今天再次深入了解了這四大天王。

以前轉過一篇部落格:http://blog.csdn.net/xxxxxx91116/article/details/12083613

但是始終太抽象,每次都要重頭看,其次,這篇文章仍然沒有很清晰的表達四大天王的特色,是以這裡給出自己的分析:

一、一個有問題,但有趣的例子

在網上看到一個有趣的例子,雖然我認為他的表述仍然是有問題的,但是有助于我們的了解:

老張愛喝茶,廢話不說,煮開水。

出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。

1 老張把水壺放到火上,立等水開。(同步阻塞)

老張覺得自己有點傻

2 老張把水壺放到火上,去客廳看電視,時不時去廚房看看水開沒有。(同步非阻塞)

老張還是覺得自己有點傻,于是變高端了,買了把會響笛的那種水壺。水開之後,能大聲發出嘀~~~~的噪音。

3 老張把響水壺放到火上,立等水開。(異步阻塞)

老張覺得這樣傻等意義不大

4 老張把響水壺放到火上,去客廳看電視,水壺響之前不再去看它了,響了再去拿壺。(異步非阻塞)

老張覺得自己聰明了。

所謂同步異步,隻是對于水壺而言。

普通水壺,同步;響水壺,異步。

雖然都能幹活,但響水壺可以在自己完工之後,提示老張水開了。這是普通水壺所不能及的。

同步隻能讓調用者去輪詢自己(情況2中),造成老張效率的低下。

所謂阻塞非阻塞,僅僅對于老張而言。

立等的老張,阻塞;看電視的老張,非阻塞。

情況1和情況3中老張就是阻塞的,媳婦喊他都不知道。雖然3中響水壺是異步的,可對于立等的老張沒有太大的意義。是以一般異步是配合非阻塞使用的,這樣才能發揮異步的效用。

作者:愚抄

連結:http://www.zhihu.com/question/19732473/answer/23434554

來源:知乎

著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

二、上述例子的問題和理論分析

上面的例子很形象吧?可以我認為他是有問題的,問題在哪裡呢?

先給出三張不同模式下的系統互動圖:

A、同步阻塞模式

【高并發程式設計】再談同步、異步、阻塞、非阻塞

B、同步非阻塞模式

【高并發程式設計】再談同步、異步、阻塞、非阻塞

C、異步非阻塞模式

【高并發程式設計】再談同步、異步、阻塞、非阻塞

好的,看完這三個圖,你應該在想,這是什麼鬼,不想看了。再聽我啰嗦2句,你就可以跳到下面看小張和狗狗的故事了。

從上面的圖可以看出來,其實不管是任何模式,核心的處理方式都是一樣的,都是

1. wait for data(等待資料);

2. copy data from kernel to user(拷貝資料到使用者層)。

而産生這三種模式的差别在于中間使用的api函數不同。

這和上面的小故事可是有一些差别的。上面的例子中,小張相當于我們的應用程式,而響水壺和普通水壺相當于核心。這就有問題了,其實我們的核心都是相同的,并不存在響水壺和普通水壺的差别,那麼怎麼樣描述才正确呢?

三、正确的例子(我很好玩!)

小張喜歡喝咖啡,同時養了好多狗;

出場:

1. 小張:相當于我們的用戶端程序

2. 小狗大黑:阻塞處理的IO函數

3. 小狗大黃:非阻塞處理的IO函數

4. 小狗大白、大紅:異步處理的IO函數

同步阻塞:

小張派大黑去看咖啡煮好沒,大黑等咖啡煮開了才回來;

同步非阻塞:

小張派大黃去看咖啡煮好沒,大黃看了一眼就回來了,過了一會,再大黃再去看看咖啡煮好沒;

異步非阻塞:

小張派大白和大紅去看咖啡煮好沒,大白和大紅到了廚房後,大白就回來告訴小張,大紅已經到廚房啦;過了一會咖啡煮好了,大紅回到客廳告訴小張

異步阻塞:(這個太傻了,目前還沒遇到)

小張派大白和大紅去看咖啡煮好沒,大白和大紅到了廚房後,一起在那等着;過了一會咖啡煮好了,大紅大白一起回到客廳告訴小張

那麼采用何種方式,要看小張有沒有養這個類型的狗(系統有沒有相關API),在有的情況下,就看小張個人的需求了(業務需求)