構造併發程序的三種基本方法和優缺點

構造併發程序的三種基本方法

進程

用這種方法,每一個邏輯控制流都是一個進程,由內核來調度維護.由於進程有獨立的虛擬地址空間,想要和其餘流通訊,控制流必須使用某種顯式的進程間通訊機制.程序員

I/O多路複用

在這種形式的併發編程中,應用程序在一個進程的上下文中顯式地調度它們本身的邏輯流.邏輯流被模型化爲狀態機,數據到達文件描述符後,主程序顯式地從一個狀態轉換到另外一個狀態.由於程序是一個單獨的進程,因此全部的流都共享同一個地址空間.編程

假設要求編寫一個echo服務器,它也能對用戶從標準輸入鍵入的交互命令作出響應.在這種狀況下,服務器必須響應兩個相互獨立的I/O事件:<font color="red">1)網絡客戶端發起鏈接請求</font>,<font color="SeaGreen">2)用戶在鍵盤上鍵入命令行</font>.咱們先等待哪一個事件呢?沒有哪一個選擇是理想的.若是在accept中等待一個鏈接請求,咱們就不能響應輸入的命令.相似的,若是在read中等待一個輸入命令,咱們就不能響應任何鏈接請求.服務器

針對這種困境的一個解決辦法就是I/O多路複用技術.基本的思路就是使用select函數,要求內核掛起進程,只有一個或多個I/O事件發生後,纔將控制返回給應用程序.網絡

線程

線程是運行在一個單一進程上下文中的邏輯流,由內核進行調度.你能夠把線程當作是其餘兩種方式的混合體,像進程流同樣由內核進行調度,而像I/O多路複用流同樣共享同一個虛擬地址空間.併發

在一些重要方面,線程執行是不一樣於進程的.由於一個線程的上下文要比一個進程的上下文小得多,線程的上下文切換要比進程的上下文切換快得多.另外一個不一樣就是線程不像進程那樣,不是按照嚴格的父子層次來組織的.和一個進程相關的線程組成一個對等(線程)池,獨立於其餘線程建立的線程.主線程和其餘線程的區別僅在於它老是進程中第一個運行的線程.對等(線程)池概念的主要影響是,一個線程能夠殺死它的任何對等線程,或者等待它的任意對等線程終止.另外,每一個對等線程都能讀寫相同的共享數據.函數

構造併發程序的三種基本方法的優劣

進程的優劣

在父進程與子進程間共享狀態信息,進程有一個很是清晰的模型: 共享文件表,可是不共享用戶地址空間.進程有獨立的地址空間既是優勢也是缺點.這樣一來,一個進程不可能不當心覆蓋另外一個進程的虛擬地址,這就消除了許多使人疑惑的錯誤--這是一個明顯的優勢.工具

另外一方面,獨立的地址空間使得進程共享狀態信息變得更加困難.爲了共享信息,它們必須使用顯式的IPC(進程間通訊).基於進程的設計的另外一個缺點是,它們每每比較慢,由於進程控制和IPC的開銷很高.編碼

I/O多路複用的優劣

事件驅動設計的一個優勢是,它比基於進程的設計給了程序員更多的對程序行爲的控制.spa

另外一個優勢是,一個基於I/O多路複用的事件驅動服務器是運行在單一進程上下文中的,所以每一個邏輯流都能訪問該進程的所有地址空間.這使得流之間共享數據變得很容易.一個與做爲單個進程運行相關的優勢是,你能夠利用熟悉的調試工具來調試你的併發服務器,就像對順序程序那樣.最後,事件驅動設計經常比基於進程的設計要高效不少,由於他們不須要進程上下文切換來調度新的流.命令行

事件驅動設計的一個明顯缺點就是編碼複雜,隨着併發粒度的減少,複雜性還會上升.基於事件的設計另外一個重要缺點是它們不能充分利用多核處理器.

相關文章
相關標籤/搜索