为啥当我尝试读取管道时管道会挂起?

Posted

技术标签:

【中文标题】为啥当我尝试读取管道时管道会挂起?【英文标题】:Why do Pipes Hang When I try to Read Them?为什么当我尝试读取管道时管道会挂起? 【发布时间】:2021-05-16 01:47:32 【问题描述】:

我正在制作一个启动子进程并通过匿名管道进行通信的程序。当我从管道读取时,程序在第一个 ReadLine() 调用处挂起,如以下代码方法所示:

// Reads messages sent from module's process via anonymous pipe
        internal string[] ReadPipe() 
            try 
                Log.Verbose("Checking read pipe");

                // Check for sync message and return null if there is no message to receive
                string pipeMessage = _pipeInReader.ReadLine(); // HANGS ON THIS LINE
                if(pipeMessage == null || !pipeMessage.StartsWith("SYNC")) 
                    Log.Verbose("No message found in pipe");
                    return null;
                

                // Return array of message lines
                Log.Verbose("Received message from module ModuleName", _fileInfo.Name);
                List<string> pipeMessageLines = new();
                do 
                    pipeMessage = _pipeInReader.ReadLine();
                    pipeMessageLines.Add(pipeMessage);
                    Log.Debug(pipeMessage);
                 while(pipeMessage != null && !pipeMessage.StartsWith("END"));

                return pipeMessageLines.ToArray();
             catch(Exception e) 
                Log.Error(e.ToString());
                return null;
            
        

我用来写入管道的代码如下:

// Sends a message to module's process via anonymous pipe
        public static void WritePipe(string message) 
            try 
                Log.Verbose("Sending \"Message\" to kit pipe", message);
                
                // Send sync message and wait for module process to receive it
                Log.Verbose("Waiting for pipe drain");
                _pipeOutWriter.Write("SYNC");
                _pipeOut.WaitForPipeDrain();

                // Send the specified message
                Log.Verbose("Pipe drained. Sending message");
                _pipeOutWriter.Write(message);
                _pipeOutWriter.Write("END");

             catch(Exception e) 
                Log.Error(e.ToString());
            
        

为什么它会挂在ReadLine() 行? 提前致谢!

【问题讨论】:

【参考方案1】:

如果没有正确的minimal, reproducible example,就无法确定。但是,您的代码的一个明显问题是,当您写入_pipeOutWriter 对象时,您不会调用Flush()。假设这是一个TextWriter,默认情况下它将缓冲数据,直到内部缓冲区已满,并且在此之前不会向底层Stream 发送任何内容。

通过调用Flush(),您可以强制它刷新其内部缓冲区并立即发送数据。

如果这不能解决您的问题,请edit the question 改进它,确保提供minimal, reproducible example,以及有关您迄今为止为解决问题所做的尝试以及您需要帮助的任何其他详细信息与。

【讨论】:

以上是关于为啥当我尝试读取管道时管道会挂起?的主要内容,如果未能解决你的问题,请参考以下文章

两个进程之间使用的命名管道有啥问题?

Rails 资产管道挂起

当阅读器断开连接时,命名管道 (FIFO) 数据会去哪里?

为啥从管道读取会阻塞进程?

C中的命名管道读取奇怪的结果

为啥 bash 在写入命名管道时关闭?