leader/follower, 半同步半非同步 和 事件驅動的關係是什麼?

1. 如果leader/follower,半同步半非同步使用了epoll 是否也算事件驅動?
2. leader/follower模式, 工作模式一定是同步么? 有什麼非同步實現方法么?
3. 看到一些操作,不是很理解為什麼這樣, 如下:
fd , socket 非阻塞
accept(fd) 返回,EAGAIN
epoll() , epoll_wait 返回可讀,
accept(fd);
不理解: 只是監聽一個fd, 為什麼不直接在此處將socket 設阻塞來 accept(), 反正epoll_wait 也會阻塞。
4.

這句話不是很理解,非同步就是基於事件的讀寫? epoll 會阻塞住進程/線程,怎麼是非同步IO啊?


凡是說epoll是非同步IO的都是錯的。


網路編程中一般常見的epoll_wait + 非阻塞的I/O的事件驅動模型都是同步I/O,epoll只是提供了一種高效的I/O多路復用機制
在這種語境下,非同步I/O在linux下指的是aio庫,在windows下指的是iocp完成埠


L/F 模式中的leader,若按咱中國的文化看,那不是 「領導」。那是 前台接待服務區生。不過這家公司比較民主,並且員工比較全能。服務生接待了一個客人,就會直接帶著客人去辦事。

傳統公司不是這樣的,傳統公司服務生通常是專職接待的前台小妹妹,接到客人後通常是:您找誰?我找你們總經理。好,我帶你去總經理辦公室……服務生和總經理都是線程,傳統模式下,請求方要要完成的工作,必須(至少在兩個)在線程間有個交接或切換的環節(過程),這會帶來損耗。所以有L/F模式存在。

這裡面對請求方來說,有同步非同步的事情存在嗎?


謝邀。

Google一下找到的第一個就很解決問題啊:http://www.kircher-schwanninger.de/michael/publications/lf.pdf

主要矛盾是吞吐量和消耗的資源。並發可以提高吞吐量,是因為計算可以在等IO的時間進行,常用的並發方式是開線程,通過內存換CPU時間,從而換吞吐量。但是,有很多線程都在對同一個對象進行IO,還不如讓少數線程進行IO省資源。半同步/半非同步就是一種思路:

簡單的說,半同步/半非同步的模式,是在IO線程層面非同步,把數據塞進一個同步隊列,然後demultiplexing,一堆線程同步地處理數據。這個模型中,IO層面用非同步,相比一個線程一個鏈接的模式,省去了很多線程維護開銷,但由於隊列資源是線程共享內容,在進隊列/出隊列的時候,免不了會有race condition。

leader/follower解決的問題主要就是IO demultiplexing中不夠有效率的地方,leader線程去監聽IO,避免多個線程監聽造成的race condition,有數據需要處理時,如果自己處理,就叫其他空著的follower去做leader;如果要follower處理,自己可以繼續做leader。任何時間,系統都只有一個leader線程在監聽IO,而處理IO的,可以有多個線程(通常是一個線程池)。當所有線程在忙的是,IO事件會自動排隊,等待leader空出來處理。

題主的問題我理解的是,follower工作的模式是否必須要同步,不可以非同步(事件驅動)嗎?

我的回答是,當然可以了。主要看你解決了什麼樣的問題:如果follower需要等待很多IO,則follower也可以用非同步(實際也成為二級leader了)。但通常的場景是,follower只處理一個IO,follower阻塞時,線程池裡面的其他follower會出來工作啊,所以使用同步更加簡單。再次注意,leader/follower模式解決的問題是IO demulitplexing,你沒有demultiplexing的需求時,本來就服務一個對象,該等待還是得等待,沒有其他對象等著需要服務,為啥要非同步?

另外,阻塞和非同步不是同一個概念,並不是說非同步就沒有阻塞了,IO該阻塞的還是得阻塞,同步下是連同處理IO的線程一起阻塞,而非同步是一個IO的阻塞不會影響到其他IO(內核通過EAGAIN告訴你,IO阻塞了一會兒再來試試),從而使得單一線程就可以服務多個IO。而實現非同步的方式,在Linux上就是基於事件通知方式,早期是O(n)的select,現在是效率更高O(1)的epoll;不用事件驅動,就要消耗CPU不斷地去read/write問,想睡覺又不知道睡多久,不經濟。

P.S. 很多概念還是有混淆的危險,怕沒說清楚,稍微整理下。
- 線程的同步說的是不同線程間交換資源需要保證的內存一致性。
- IO的同步/非同步說的是IO讀寫模式是否是阻塞模式,非阻塞模式下,一個IO的阻塞不會引起線程的阻塞,線程還可以處理其他IO和進行運算;阻塞模式下,IO阻塞了,線程就睡覺去了。
- 事件驅動+同步IO有什麼意義嗎?反倒是非同步IO需要事件驅動,所以談論事件驅動,通常語境下等同於談論非同步IO。同樣,事件驅動下線程的阻塞和IO的阻塞不是一回事,事件驅動的阻塞是真沒事幹可以睡覺去了;而IO的阻塞是一個設備還沒準備好要等,同時很可能其他設備已經準備好了,不一定沒事做。


epoll只是通過回調實現的偽非同步,本質還是阻塞同步的。
Linux下真正的非同步io庫叫aio。
還有一種叫信號io。

另外使用epoll是因為io復用。


我認為這篇文章對同步,非同步,阻塞,非阻塞的概念講解的非常清楚。
http://m.blog.csdn.net/blog/historyasamirror/5778378


推薦閱讀:

你用socket寫過什麼有趣的程序?
Linux中本機和本機Socket通信會走網卡嗎?

TAG:伺服器 | Socket | Linux開發 |