C 匿名管道的理解與實現

2021-09-24 20:18:21 字數 2154 閱讀 1927

什麼是匿名管道?

匿名管道用於程序之間通訊,且僅限於本地父子程序之間通訊,結構簡單,類似於一根水管,一端進水另一端出水(單工)。相對於命名管道,其占用小實現簡單,在特定情況下,比如實現兩圍棋引擎本地對戰可以使用匿名管道。

怎樣實現匿名管道雙向通訊?

由於匿名管道是單工的,所以為實現父子程序雙向通訊需要建立兩根管道,並由子程序繼承一根管道的讀控制代碼和另一根管道的寫控制代碼。

如何理解匿名管道的雙向通訊?

管道相當於一段記憶體,乙個程序輸入,乙個程序讀出。

在程序通訊時一般會產生程序同步問題(程序同步講解請見作業系統類書籍):父子程序各自均具有讀寫功能,在管道為空時,相應讀程序應該被阻塞起來,直到管道被寫入為止才被喚醒。

這種空管道不允許讀的特性應當加乙個鎖,但匿名管道自帶了這種功能,所以不需要對讀寫進行限制,其能自動阻塞。

在vs2017下實現匿名管道

對幾個基本點進行介紹

#include

匿名管道需要包含此標頭檔案

首先我們需要了解一下最後程式實現中我想要的效果:父程序輸入任意長數字(當然侷限於匿名管道的最大大小4mb)通過匿名管道傳給子程序,由子程序對該字串(由於在管道中以字元流形式存在)的各位數進行加和,把這個加和的結果返回父程序。

int bitadd(char *ary1, char *ary2, unsigned long len, int lcount);

其中ary1為子程序接收到的字串、ary2為計算結果、len是接收到的字串長度、lcount為計算結果長度。

建立管道

函式原型:

bool winapi createpipe( 

_out_phandle hreadpipe, 

_out_phandle hwritepipe, 

_in_opt_lpsecurity_attributes lppipeattributes,

_in_dword nsize);

實際呼叫形式:

createpipe(&read, &write, &sa, 0);

其中read是讀控制代碼,write是寫控制代碼,sa是管道安全屬性,0代表管道緩衝設定為系統預設值。

由上函式可知在建立管道之前,需要先設定管道安全屬性。

設定管道安全屬性

物件原型:

typedef struct _security_attributes security_attributes,* psecurity_attributes;

​在程式中僅需如下設定即可:(parentview為我建立的父程序管道類)

void parentview::createattributes()  // 設定管道安全屬性

各引數在原型中已有很好的注釋。

建立好管道後,可以考慮建立子程序,使其繼承父程序的管道控制代碼。

建立子程序

先貼**:

這裡也不貼createprocess的函式原型了,**塊中有較好的注釋。

其實對於管道建立和子程序建立都是乙個模版框架。

讀寫函式請見github源**

實現雙向通訊

在父程序中建立兩個匿名管道。此時父程序共有六個控制代碼read1,write1,read2,write2,標準輸入輸出控制代碼。

由圖所示,標準輸入輸出控制代碼用於在dos視窗的輸入和輸出。

然後我們需要讓建立的子程序繼承write1控制代碼和read2控制代碼。

子程序初始化控制代碼**

read = getstdhandle(std_input_handle); // 繼承控制代碼

write = getstdhandle(std_output_handle);

if ((read == invalid_handle_value) || (write == invalid_handle_value))

cout << "繼承控制代碼無效" << endl;

可以看到,子程序的標準輸入輸出控制代碼已經被繼承的write1控制代碼和read2控制代碼所覆蓋。

因此無法實現在子程序的dos視窗進行顯示,子程序視窗將是永遠黑窗,可以在父程式中注釋掉子程序所繼承的寫控制代碼進行對比,並將createprocess函式中的乙個引數設定為顯示子程序視窗(注釋中有)。

需要注意的坑點:

si.dwflags |= startf_usestdhandles;

若要實現雙向通訊,子程序dos是黑窗。但是可以將子程序收到的結果寫到檔案。

命名管道與匿名管道

匿名管道 父程序 include include main process information pp 定義結構體security attributes變數 char text 匿名管道程式測試!dword writetext ss.nlength sizeof ss 填充結構體中的各成員 ss....

Linux 匿名管道pipe與命名管道FIFO

什麼是管道 功能 建立匿名管道 引數 fd 檔案描述符陣列,其中fd 0 表 示讀端,fd 1 表 示寫端 返回值 成功返回0,失敗返回錯誤 實現 include include include include int main memset buf,0x00,sizeof buf 從管道中讀取 i...

匿名管道實現程序資訊交換

通過建立兩個匿名管道來實現主程序與cmd.exe程序的通訊,在主程序輸入命令後將命令傳送到cmd.exe程序進行執行,執行完成後返回執行結果到主程序並顯示 程式作用 通過建立的匿名管道與建立的cmd程式通訊,並將cmd中的結果返回 此處是將本程式和乙個已經存在的可執行程式連線起來進行通訊 inclu...