尝试将 StreamWriter 打开到命名管道时,Mono 挂起

Posted

技术标签:

【中文标题】尝试将 StreamWriter 打开到命名管道时,Mono 挂起【英文标题】:Mono hangs when trying to open a StreamWriter to a named pipe 【发布时间】:2017-10-05 22:03:12 【问题描述】:

我正在编写的程序是在 linux 中使用 FIFO 管道进行进程间通信。充其量是相当hacky,但不管我有什么问题。

        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 或两者)时,程序都会挂起。没有错误或任何东西。它也挂在调试器中。

最好的部分是......它曾经工作过。我让进程间通信正常工作,然后它就莫名其妙地停止了。除了您在此处看到的内容外,我注释掉了所有内容,重新启动了我的系统,重新创建了管道等,但无济于事。是什么赋予了?是我的代码有问题还是系统上的其他东西在干扰?

【问题讨论】:

我不知道它是否对你有帮助,但我过去曾遇到过将路径连接在一起的问题。一天有效,下一天无效!我的解决方案是在路径上使用 Path.Combine(...) ,这阻止了不一致的行为。 【参考方案1】:

这是设计使然。尝试以下操作:打开 2 个 bash 终端,创建一个管道,然后在其中一个终端中读取它并在另一个终端中写入它。例如

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

>cat test.fifo

你会看到无论顺序如何,每一方都在等待另一方。

进程 1 的输入管道是进程 2 的输出管道,反之亦然。如果两个进程使用相同的代码访问管道,进程 1 会读取其输入管道并阻塞等待进程 2 写入内容。进程 2 也读取它的输入管道并等待进程 1 写入,但进程 1 正在等待,甚至还没有打开另一个管道。僵局。

解决此问题的一种方法是在单独的线程中运行读取器或写入器。这样,进程 1 和 2 将打开两个管道,并且解决了僵局。

另一个选项是异步打开管道。我的 C# 生锈了,但是 *** 上有很多例子:

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

NamedPipeServerStream in Mono

基本上将 NamedPipeServerStream 传递给读取器/写入器。

我怀疑它以前工作过,因为 P1 打开了 Reader,然后是 Writer,而 P2 打开了 Writer,然后是 Reader,从而解除了 P1 的阻塞。

【讨论】:

以上是关于尝试将 StreamWriter 打开到命名管道时,Mono 挂起的主要内容,如果未能解决你的问题,请参考以下文章

为啥只读打开命名管道块?

命名管道提供程序无法打开与 SQL Server 1231 的连接

打开命名管道时,构造函数上的 FileInputStream 块

Linux:打开命名管道进行写入时超时

具有多个读取器的 Unix 上的命名管道 (FIFO)

检测命名管道的关闭