2017-05-08 74 views
10

我正在編寫的程序是在Linux中使用FIFO管道進行進程間通信。充其量只是黑客,但不管我有問題。單聲道在嘗試打開StreamWriter到命名管道時掛起

 if (!File.Exists(Path.GetTempPath() + "gminput.pipe")) 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/usr/bin/mkfifo", Arguments = Path.GetTempPath() + "gminput.pipe", }; 
      Process proc = new Process() { StartInfo = startInfo, }; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 
     if (!File.Exists(Path.GetTempPath() + "gmoutput.pipe")) 
     { 
      ProcessStartInfo startInfo = new ProcessStartInfo() { FileName = "/usr/bin/mkfifo", Arguments = Path.GetTempPath() + "gmoutput.pipe", }; 
      Process proc = new Process() { StartInfo = startInfo, }; 
      proc.Start(); 
      proc.WaitForExit(); 
     } 

     using (StreamWriter outputPipe = new StreamWriter(Path.GetTempPath() + "gmoutput.pipe")) 
     using (StreamReader inputPipe = new StreamReader(Path.GetTempPath() + "gminput.pipe")) 
     { 
      Console.WriteLine("This code is never reached!"); 
     } 

我所做的只是檢查管道是否已經存在,如果沒有,請致電mkfifo創建它。這部分似乎工作正常,命名管道正確創建。每當我嘗試打開它們(無論是StreamWriter,StreamReader,還是兩者),該程序只是掛起。沒有錯誤或任何東西。它也掛在調試器中。

最好的部分是......它曾經工作。我有進程間通信工作,然後它只是莫名其妙地停止。除了你在這裏看到的東西,我重新評論了一切,重新啓動了我的系統,重新創建了管道等,但都無濟於事。是什麼賦予了?我的代碼有什麼問題,或者系統上的其他內容有干擾?

+6

我不知道它是否會對您有所幫助,但我在過去曾將問題連接在一起的問題。有一天它工作,下一個不行!對我來說,解決方案是在路徑上使用Path.Combine(...),這可以阻止不一致的行爲。 –

回答

3

這是設計。嘗試以下方法:打開2個bash端子,創建一個管道,然後在其中一個端子中讀取並在另一個端子中寫入。例如

>mkfifo test.fifo 
>echo "test" > test.fifo 

>cat test.fifo 

你會看到,無論順序如何,每一方都會阻止等待另一方。

流程1的輸入管道是流程2的輸出管道,反之亦然。如果兩個進程都使用相同的代碼來訪問管道,那麼進程1將讀取其輸入管道,並等待進程2寫入數據塊。進程2還讀取它的輸入管道,等待進程1寫入,但進程1正在等待,甚至沒有打開另一個進程。僵局。

解決此問題的一種方法是在單獨的線程中運行讀取器或寫入器。這種方式可以打開兩個管道並解決網格鎖問題。

另一種選擇是異步打開管道。我的C#是生鏽的,但也有很多的例子在計算器:

How to do a non-waiting write on a named pipe (c#)?

NamedPipeServerStream in Mono

基本上傳遞NamedPipeServerStream到讀/寫器。

我懷疑它以前工作過,因爲P1打開Reader,然後Writer,P2打開Writer,然後Reader打開P1。