2017-05-08 38 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。