half-sync/half-async 和 Leader/Followers 模式的主要区别
生活随笔
收集整理的這篇文章主要介紹了
half-sync/half-async 和 Leader/Followers 模式的主要区别
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
在 《POSA2》 一書中,關(guān)于這兩個模式有兩個很形象的比喻:
半同步/半異步(half-sync/half-async):
許多餐廳使用 半同步/半異步 模式的變體。例如,餐廳常常雇傭一個領(lǐng)班負責(zé)迎接顧客,并在餐廳繁忙時留意給顧客安排桌位,為等待就餐的顧客按序排隊是必要的。領(lǐng)班由所有顧客“共享”,不能被任何特定顧客占用太多時間。當顧客在一張桌子入坐后,有一個侍應(yīng)生專門為這張桌子服務(wù)。
領(lǐng)導(dǎo)者/追隨者(Leader/Followers):
在日常生活中,領(lǐng)導(dǎo)者/追隨者模式用于管理許多飛機場出租車候車臺。在該用例中,出租車扮演“線程”角色,排在第一輛的出租車成為 領(lǐng)導(dǎo)者,剩下的出租車成為 追隨者。同樣,到達出租車候車臺的乘客構(gòu)成了必須被多路分解給出租車的事件,一般以先進先出排序。一般來說,如果任何出租車可以為任何顧客服務(wù),該場景就主要相當于 非綁定句柄/線程關(guān)聯(lián)。然而,如果僅僅是某些出租車可以為某些乘客服務(wù),該場景就相當于 綁定句柄/線程關(guān)聯(lián)。
在 《POSA2》 書中列舉的例子都比較復(fù)雜,并且書上沒有列出完整的代碼。但是這兩個模式其實都可以在 《unix網(wǎng)絡(luò)編程》一書中找到對應(yīng)的完整的代碼和相關(guān)的討論。
在 半同步/半異步 模式中,需要由模式實現(xiàn)者顯示構(gòu)造一個隊列,以便同步層和異步層可以通信。
在 《unix網(wǎng)絡(luò)編程》 一書的 “27.12 TCP預(yù)先創(chuàng)建線程服務(wù)器程序,主線程統(tǒng)一 accept” 的例子中, 如果只是從處理 accept 這個事件上看,可以認為這是一個使用了 半同步/半異步 模式的例子。但是從具體的業(yè)務(wù)處理(即web_child的處理上),仍然可以認為是一個ThreadPerConnection模型,因為在 thread_main 中直接讀取請求和發(fā)送響應(yīng)。在這個例子中,就有一個隊列:
Java代碼 ?[b]//這就是一個典型的循環(huán)隊列的定義,iget?是隊列頭,iput?是隊列尾[/b]?? int?clifd[MAXNCLI],?iget,?iput;??? ?? int?main(?int?argc,?char?*?argv[]?)?? {?? ??......?? ??int?listenfd?=?Tcp_listen(?NULL,?argv[?1?],?&addrlen?);?? ??......?? ?? ??iget?=?iput?=?0;?? ?? ??for(?int?i?=?0;?i?<?nthreads;?i++?)?{?? ????pthread_create(?&tptr[i].thread_tid,?NULL,?&thread_main,?(void*)i?);?? ?? ??for(?;?;?)?{?? ????connfd?=?accept(?listenfd,?cliaddr,,?&clilen?);?? ????clifd[?iput?]?=?connfd;?????[b]//?接受到的連接句柄放入隊列[/b]?? ????if(?++iput?==?MAXNCLI?)?iput?=?0;???? ??}?? }?? ?? void?*?thread_main(?void?*?arg?)?? {?? ??for(?;?;?)?{?? ????while(?iget?==?iput?)?pthread_cond_wait(?......?);?? ????connfd?=?clifd[?iget?];?????[b]//?從隊列中獲得連接句柄[/b]?? ????if(?++iget?==?MAXNCLI?)?iget?=?0;?? ????......?? ????web_child(?connfd?);?? ????close(?connfd?);?? ??}?? }??
而在 領(lǐng)導(dǎo)者/追隨者 模式中,同樣是有一個隊列的,不過不需要模式實現(xiàn)者顯示構(gòu)造,而是直接使用了操作系統(tǒng)底層的隊列。
在 《unix網(wǎng)絡(luò)編程》 一書的 “27.11 TCP 預(yù)先創(chuàng)建服務(wù)器線程,每個線程各自 accept ” 的例子中,就是直接使用了操作系統(tǒng)中關(guān)于 accept 的隊列。這個例子可以認為是 領(lǐng)導(dǎo)者/追隨者 模式的一個例子。
Java代碼 ?int?listenfd;?? ?? int?main(?int?argc,?char?*?argv[]?)?? {?? ??......?? ??listenfd?=?Tcp_listen(?NULL,?argv[?1?],?&addrlen?);?? ??......?? ??for(?int?i?=?0;?i?<?nthreads;?i++?){?? ????pthread_create(?&tptr[i].thread_tid,?NULL,?&thread_main,?(void*)i?);?? ??}?? ??......?? }?? ?? void?*?thread_main(?void?*?arg?)?? {?? ??for(?;?;?){?? ????......?? ????[b]//?多個線程同時阻塞在這個?accept?調(diào)用上,依靠操作系統(tǒng)的隊列[/b]?? ????connfd?=?accept(?listenfd,?cliaddr,?&clilen?);?? ????......?? ????web_child(?connfd?);?? ????close(?connfd?);?? ????......?? ??}?? }??
當然,這里提到的操作系統(tǒng)的隊列,在 半同步/半異步 模式中雖然沒有明顯地指出來,但只要是通過操作系統(tǒng)來做 accept ,那么在 半同步/半異步 模式中仍然會隱式地用到。
在 《POSA2》中,作者的評價:
因為半同步/半異步設(shè)計在 web 服務(wù)器虛擬內(nèi)存而不是操作系統(tǒng)內(nèi)核內(nèi)排隊請求,所以它更具伸縮性。
看了上面的代碼之后,明白了為何 ACE 的作者在 《C++網(wǎng)絡(luò)編程2》 中特意引用了一首詩來“表達我們對 Richard 之持久影響的看法”:
不是在悲哀的冥河之濱,也不是在遙遠的
樂土般的平原的清輝中,我們將在死者中間
遇見那些我們一直是其學(xué)生的人 ... ...
我們還將相遇,分離,再相遇,
在死者們相遇的地方,在活著的人的唇上
關(guān)于不同的客戶-服務(wù)器編程模型,在 《unix網(wǎng)絡(luò)編程》的 “第27章 客戶-服務(wù)器程序的其他設(shè)計方法”中討論得很充分,對每種模型的性能也做了很好的分析。
半同步/半異步(half-sync/half-async):
許多餐廳使用 半同步/半異步 模式的變體。例如,餐廳常常雇傭一個領(lǐng)班負責(zé)迎接顧客,并在餐廳繁忙時留意給顧客安排桌位,為等待就餐的顧客按序排隊是必要的。領(lǐng)班由所有顧客“共享”,不能被任何特定顧客占用太多時間。當顧客在一張桌子入坐后,有一個侍應(yīng)生專門為這張桌子服務(wù)。
領(lǐng)導(dǎo)者/追隨者(Leader/Followers):
在日常生活中,領(lǐng)導(dǎo)者/追隨者模式用于管理許多飛機場出租車候車臺。在該用例中,出租車扮演“線程”角色,排在第一輛的出租車成為 領(lǐng)導(dǎo)者,剩下的出租車成為 追隨者。同樣,到達出租車候車臺的乘客構(gòu)成了必須被多路分解給出租車的事件,一般以先進先出排序。一般來說,如果任何出租車可以為任何顧客服務(wù),該場景就主要相當于 非綁定句柄/線程關(guān)聯(lián)。然而,如果僅僅是某些出租車可以為某些乘客服務(wù),該場景就相當于 綁定句柄/線程關(guān)聯(lián)。
在 《POSA2》 書中列舉的例子都比較復(fù)雜,并且書上沒有列出完整的代碼。但是這兩個模式其實都可以在 《unix網(wǎng)絡(luò)編程》一書中找到對應(yīng)的完整的代碼和相關(guān)的討論。
在 半同步/半異步 模式中,需要由模式實現(xiàn)者顯示構(gòu)造一個隊列,以便同步層和異步層可以通信。
在 《unix網(wǎng)絡(luò)編程》 一書的 “27.12 TCP預(yù)先創(chuàng)建線程服務(wù)器程序,主線程統(tǒng)一 accept” 的例子中, 如果只是從處理 accept 這個事件上看,可以認為這是一個使用了 半同步/半異步 模式的例子。但是從具體的業(yè)務(wù)處理(即web_child的處理上),仍然可以認為是一個ThreadPerConnection模型,因為在 thread_main 中直接讀取請求和發(fā)送響應(yīng)。在這個例子中,就有一個隊列:
Java代碼 ?
而在 領(lǐng)導(dǎo)者/追隨者 模式中,同樣是有一個隊列的,不過不需要模式實現(xiàn)者顯示構(gòu)造,而是直接使用了操作系統(tǒng)底層的隊列。
在 《unix網(wǎng)絡(luò)編程》 一書的 “27.11 TCP 預(yù)先創(chuàng)建服務(wù)器線程,每個線程各自 accept ” 的例子中,就是直接使用了操作系統(tǒng)中關(guān)于 accept 的隊列。這個例子可以認為是 領(lǐng)導(dǎo)者/追隨者 模式的一個例子。
Java代碼 ?
當然,這里提到的操作系統(tǒng)的隊列,在 半同步/半異步 模式中雖然沒有明顯地指出來,但只要是通過操作系統(tǒng)來做 accept ,那么在 半同步/半異步 模式中仍然會隱式地用到。
在 《POSA2》中,作者的評價:
因為半同步/半異步設(shè)計在 web 服務(wù)器虛擬內(nèi)存而不是操作系統(tǒng)內(nèi)核內(nèi)排隊請求,所以它更具伸縮性。
看了上面的代碼之后,明白了為何 ACE 的作者在 《C++網(wǎng)絡(luò)編程2》 中特意引用了一首詩來“表達我們對 Richard 之持久影響的看法”:
不是在悲哀的冥河之濱,也不是在遙遠的
樂土般的平原的清輝中,我們將在死者中間
遇見那些我們一直是其學(xué)生的人 ... ...
我們還將相遇,分離,再相遇,
在死者們相遇的地方,在活著的人的唇上
關(guān)于不同的客戶-服務(wù)器編程模型,在 《unix網(wǎng)絡(luò)編程》的 “第27章 客戶-服務(wù)器程序的其他設(shè)計方法”中討論得很充分,對每種模型的性能也做了很好的分析。
總結(jié)
以上是生活随笔為你收集整理的half-sync/half-async 和 Leader/Followers 模式的主要区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行白金卡多久下卡/审核多长时间
- 下一篇: 通货膨胀通俗意思是什么?对居民有什么影响