c# - Process.StandardOutput.ReadToEnd() 中的死锁问题;

标签 c# process deadlock

read这部分代码可能会导致死锁:

 Process p = new Process();

 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "Write500Lines.exe";
 p.Start();
 p.WaitForExit();
 string output = p.StandardOutput.ReadToEnd();

因为

A deadlock condition can result if the parent process calls p.WaitForExit before p.StandardOutput.ReadToEnd and the child process writes enough text to fill the redirected stream. The parent process would wait indefinitely for the child process to exit. The child process would wait indefinitely for the parent to read from the full StandardOutput stream.

但我不太明白为什么。我的意思是,在这种情况下,什么是父进程,什么是子进程?

最佳答案

简而言之,这就是可能发生的情况:

应用程序 A(您上面的代码)启动子进程 B 并重定向标准输出。然后A等待B进程退出。当 A 等待 B 退出时,B 将输出生成到输出流(A 已重定向)。此流的缓冲区大小有限。如果缓冲区已满,则需要将其清空以便 B 能够继续写入。由于 A 在 B 退出之前不会读取,因此您可能会遇到这样一种情况,即 B 将等待输出缓冲区清空,而 A 将等待 B 退出。双方都在等待对方采取行动,你陷入了僵局。

您可以尝试以下代码来演示问题:

ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = "cmd";
psi.Arguments = @"/c dir C:\windows /s";
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
p.WaitForExit();
string output = p.StandardOutput.ReadToEnd();

这将(很可能)产生输出流已满的情况,以便子进程(在本例中为 "cmd")将等待它被清除,而上面的代码将等待 cmd 完成。

关于c# - Process.StandardOutput.ReadToEnd() 中的死锁问题;,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1475970/

相关文章:

c - 随机运行实例的段错误

Java 死锁与 Eclipse CDT headless 构建

c# - 编写/编译通用 Ninject 绑定(bind)时出现问题

c# - 通过套接字动态配置 .NET 客户端

c# - 如何使用 C# 中的 select 调用 MySQL 存储过程

c++ - 如何在 Emacs 中终止正在运行的进程

C#,动态对象名称?

c# - 我怎样才能得到我的应用程序的父进程的PID

macos - 我不能运行超过 100 个进程

mysql - "FOR UPDATE"v/s "LOCK IN SHARE MODE": Allow concurrent threads to read updated "state" value of locked row