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

发布于 2024-08-05 23:37:41 字数 677 浏览 6 评论 0原文

读到这部分代码可能会导致僵局:

 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();

因为

如果出现以下情况,可能会导致死锁情况 父进程调用p.WaitForExitp.StandardOutput.ReadToEnd 之前和 子进程写入足够的文本 填充重定向的流。这 父进程将无限期地等待 以便子进程退出。这 子进程将无限期地等待 供家长阅读全文 标准输出流。

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

I read that this portion of code can cause deadlock:

 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();

Because

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.

But I don't quite why. I mean, in this case here, what's the parent process, and what's the child?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

世态炎凉 2024-08-12 23:37:41

简而言之,这可能会发生:

应用程序 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 完成。

In short this is what may happen:

Application A (your code above) starts child process B and redirects standard output. Then A waits for the B process to exit. While A waits for B to exit, B produces output into the output stream (which A has redirected). This stream has a limited buffer size. If the buffer becomes full, it needs to be emptied in order to B to be able to continue writing into it. Since A is not reading until B has exited, you can end up in a situation where B will wait for the output buffer to be emptied, while A will wait for B to exit. Both are waiting for each other to take action, and you have a deadlock.

You can try the following code to demonstrate the problem:

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();

This will (moste likely) produce the situation where the output stream is full so that the child process (in this case "cmd") will wait for it to be cleared, while the code above will wait for cmd to finish.

秋风の叶未落 2024-08-12 23:37:41

父进程是调用p.Start() 的进程。我想这是你的应用程序(调用者)。
子进程是p,或者换句话说,被调用者。

The parent process is the one calling p.Start(). I guess this is your application (the caller).
The child process is p or in other words, the callee.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文