Windows系列作業系統對處理序間通訊的支援――管道與郵路

來源:互聯網
上載者:User
最近用C++編寫處理序間通訊程式,用到了管道的概念,特整理如下:

Windows應用程式間資料通訊的基本方式有四種。最簡單的是利用剪下板;另一種是DDE(Dynamic Data Exchange動態資料交換),它利用一種公用的協議實現兩個或多個應用程式之間的通訊;再者是通過記憶體對應檔,記憶體映射可以將一個進程的一段虛擬位址映射為一個檔案,然後其它的進程可以共用該段虛擬位址;最後就是通過管道與郵路實現進程間資料通訊。

要討論管道與郵路之前先讓我們來複習一下這幾個概念:進程、線程。微軟官方對進程和線程的定義如下:

進程:用最簡潔的話來說,進程就是一個正在執行的程式,一個或多個線程在進程中運行,線程是作業系統分配CPU運算時間的最小單位。每一個進程都提供了運行一個程式所必需的資源,一個進程具有4GB的虛擬位址空間(Windows NT Server Enterprise Edition及Windows 2000 Advanced Server中低3GB虛擬位址空間供進程使用,高1GB供作業系統的核心代碼使用。Windows NT/2000中低2GB供進程使用,高2GB供作業系統核心代碼使用。Windows9X:0――64K唯讀空間用來裝入Microsoft DOS資訊,64K――4M裝入DOS的相容代碼,4M――2GB的私人空間供進程使用,2GB――3GB的共用空間裝入各種DLL代碼,3GB――4GB為共用的系統核心代碼空間,其中共用的2GB――4GB的空間是99%的“記憶體無效頁錯誤”、“General Protect Error(GPE)”及藍屏的罪魁禍首。),可執行代碼,資料,物件控點,環境變數,優先權以及設定最大化最小化的功能。每一個進程都從一個主線程開始執行,但可以在它所擁有的線程中建立額外的線程。一個進程的所有線程共用進程的虛擬位址空間和系統資源,一個線程的資源套件括線程的機器寄存器設定,核心堆棧,線程環境變數和進程虛擬位址中的使用者堆棧。

讓我們再來看看微軟官方對管道和郵路是怎麼解釋的。

管道(pipe)是進程用來通訊的共用記憶體地區。一個進程往管道中寫入資訊,而其它的進程可以從管道中讀出資訊。如其名,管道是進程間資料交流的通道。郵路(Mailslots)的功能與管道類似,也是進程間通訊(interprocess communications,IPC)的媒介,只不過其具體實現方式與管道有些差別。一個基於Win32的應用程式可以在郵路中儲存訊息,這些訊息通常通過網路發往一個指定的電腦或某網域名稱(域是共用一個組名的一組工作站或伺服器。)下的所有電腦。你也可以使用具名管道代替郵路來進行處理序間通訊。具名管道最適合用來兩個進程間的訊息傳遞,郵路則更適合一個進程向多個進程廣播訊息。郵路具有一個重要的特點,它使用資料包廣播訊息。廣播(broadcast)是網路傳輸中使用的術語,它意味著接收方收到資料後不發送確認訊息通知發送方。而管道(這裡的管道指具名管道,有關具名管道以下詳解。)則不同,它更類似於打電話,你只對一個當事人說話,但是你卻非常清楚你的話都被對方聽到。郵路和管道一樣,也是一個虛擬檔案,它儲存在記憶體中,但是你卻必須使用普通的Win32檔案函數訪問它,比如CreateFile、ReadFile、WriteFile等。郵路中儲存的資料可以是任何形式的,唯一的要求是不得超過64K。與磁碟檔案不同的是,郵路是一個臨時的對象,當某個郵路所有的控制代碼都關閉的時候,該郵路及其中的資料就被刪除。

管道的類型有兩種:匿名管道和具名管道。匿名管道是不命名的,它最初用於在本地系統中父進程與它啟動的子進程之間的通訊。具名管道更進階,它由一個名字來標識,以使用戶端和服務端應用程式可以通過它進行彼此通訊。而且,Win32具名管道甚至可以在不同系統的進程間使用,這使它成為許多客戶/伺服器應用程式的理想之選。

就像水管串連兩個地方並輸送水一樣,軟體的管道串連兩個進程並輸送資料。一個一個管道一旦被建立,它就可以象檔案一樣被訪問,並且可以使用許多與檔案操作同樣的函數。可以使用CreateFile函數擷取一個已開啟的管道的控制代碼,或者由另一個進程提供一個控制代碼。使用WriteFile函數向管道寫入資料,之後這些資料可以被另外的進程用ReadFile函數讀取。管道是系統對象,因此管道的控制代碼在不需要時必須使用CloseHandle函數關閉。

匿名管道只能單向傳送資料,而具名管道可以雙向傳送。管道可以以位元流形式傳送任意數量的資料。具名管道還可以將資料集合到稱為訊息的資料區塊中。具名管道甚至具有通過網路連接多進程的能力。但遺憾的是Windows9X不支援建立具名管道,它只能在WindowsNT系列(如Windows NT,Windows 2000,Windows XP)的作業系統上建立。

當討論管道時,通常涉及到兩個進程:客戶進程和服務進程。服務進程負責建立管道。客戶進程串連到管道。服務進程可以建立一個管道的多個執行個體,以此支援多個客戶進程。

匿名管道用以下函數建立:

BOOL CreatePipe(
      PHANDLE hReadPipe,                       // 用於讀操作的控制代碼
      PHANDLE hWritePipe,                      // 用於寫操作的控制代碼
      LPSECURITY_ATTRIBUTES lpPipeAttributes, // 描述安全資訊的一個結構
      DWORD nSize                              // 管道大小
);

具名管道用以下函數建立:

HANDLE CreateNamedPipe(
 LPCTSTR lpName,                             // 管道名
      DWORD dwOpenMode,                           // 管道開啟檔案
     DWORD dwPipeMode,                           // 管道模式
 DWORD nMaxInstances,                        // 該管道最大的執行個體數量
 DWORD nOutBufferSize,                       // 輸出緩衝區大小
 DWORD nInBufferSize,                        // 輸入緩衝區大小
 DWORD nDefaultTimeOut,                      // 指定預設的逾時時間
 LPSECURITY_ATTRIBUTES lpSecurityAttributes // 描述安全資訊的一個結構
);

管道由以下函數刪除:

BOOL CloseHandle(
 HANDLE hObject   // 管道控制代碼
);

其它的管道函數簡介如下:

CallNamedPipe:串連到一個具名管道,讀取或寫入資料之後關閉它。

ConnectNamedPipe:服務進程準備好一個串連到客戶進程的管道,並等待一個客戶進程串連上為止。

DisconnectNamedPipe:服務端用來斷開與用戶端的串連。

GetNamedPipeHandleState:擷取一個具名管道的狀態資訊。

GetNamedPipeInfo:擷取一個具名管道的資訊。

PeekNamedPipe:從一個匿名或具名管道中拷貝資料到一個緩衝區。

SetNamedPipeHandleState:設定管道的類型及其它狀態資訊,比如說是位元流還是訊息流程管道。

TransactNamedPipe:從一個訊息管道讀訊息或向其寫入訊息。

WaitNamedPipe:客戶進程用來串連到一個具名管道。

郵路是由郵路服務進程建立。當郵路服務進程建立了一個郵路後,便返回該郵路控制代碼。當某個進程需要從該郵路中讀取訊息時,它必須提供該控制代碼。只有建立該郵路的進程,或以某種機制(比如繼承)獲得該郵路控制代碼的進程能夠從郵路中讀取訊息。與管道不同,所有的郵路都是從屬於建立它的本地進程的,你無法建立一個遠端郵路。郵路的客戶進程具有向郵路寫入訊息的許可權。任何進程只要獲得了郵路的名字,就可以往裡面寫入訊息,新的訊息將放在郵路的訊息佇列後面。

郵路能在一個域中廣播訊息。如果域中幾個進程每個都用相同的名字建立了一個郵路,則它們都會收到送往該郵路的訊息。

在郵路中傳遞的訊息如果小於425位元組,那麼它們會以資料包的形式傳遞。大於425位元組的訊息會以其它的方式傳輸,在這種情況下,你只能從一個客戶進程傳遞給一個服務進程,而不能從一個客戶進程傳遞給多個服務進程。且Windows NT不支援大於等於425個位元組的訊息傳遞。

郵路由以下函數建立:

HANDLE CreateMailslot(
 LPCTSTR lpName,                            // 郵路名
 DWORD nMaxMessageSize,                     // 訊息最大的大小
 DWORD lReadTimeout,                        // 讀取操作的逾時時間
 LPSECURITY_ATTRIBUTES lpSecurityAttributes // 描述安全資訊的一個結構
);

郵路由以下函數刪除:

BOOL CloseHandle(
 HANDLE hObject   // 郵路控制代碼
);

其它郵路函數簡介如下:

GetMailslotInfo:擷取指定郵路的相關資訊。

SetMailslotInfo:設定指定郵路的相關資訊。

Windows系列作業系統對管道和郵路的支援就是這樣,除此之外,記憶體對應檔也是進程間資料交流的重要方式,但限於篇幅,本文不再具體介紹。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.