【问题标题】:Fooling System.Diagnostics.Process WaitForExit()愚弄 System.Diagnostics.Process WaitForExit()
【发布时间】:2014-01-22 15:55:18
【问题描述】:

有一个程序 (c#) 通过 System.Diagnostics.Process 启动我的脚本,然后在其上调用 WaitForExit()。脚本(在这种情况下是 python,虽然可以是任何东西)然后生成一个子进程并退出。我希望程序继续运行,但它一直挂起,直到子进程退出。

我尝试了许多启动子进程的方法,从 python 的 os.fork 到编写 shell 脚本包装器,但每种方法都会导致程序挂起。无法更改c#程序的代码,需要对子进程做些什么才能让程序继续运行?

注意:我不知道这是否重要,但 c# 程序在 ubuntu 上以单声道运行。

编辑:在调用 WaitForExit 之前进一步审查 c# 代码后,有一个 while (!process.StandardOutput.EndOfStream) 循环,这可能是问题吗?

【问题讨论】:

  • 您是否可以控制子流程的代码,或者您必须在中间 Python 脚本中执行此操作?
  • 我可以控制两者。事实上,我的 os.fork 方法使用了一个 Python 脚本。
  • 好的,那应该更容易……让我编辑答案。
  • 作为旁注,您知道是否有任何关于 mono 如何将 .NET 进程语义映射到 POSIX 进程语义的好的文档?我在搜索中找不到任何有用的东西。
  • 我不是真正的 c# 程序员,所以不,我不知道。

标签: c# python process mono system.diagnostics


【解决方案1】:

WaitForExit 似乎挂在打开的 stdout/stderr 上。我使用这个脚本使我的脚本异步:

#!/bin/bash

~/foo.py "$@" >&- 2>&- &

希望这有助于下一个人的到来。

【讨论】:

    【解决方案2】:

    最简单的方法是让子进程setsid(),这将删除它与您的所有连接——它成为新会话的会话领导者,以及新进程组的组领导者,并且一次调用即可从您的 stdio 分离。

    如果你不能修改子进程的代码,你可以通过显式地forking,然后调用setsid,然后调用execing,从你的Python父进程中进行修改,而不是像@这样的各种常用的更干净的方法987654329@。像这样:

    pid = os.fork()
    if not pid:
        sid = os.setsid()
        os.execv(path, args)
    

    我相信对System.Diagnostics.Process 来说重要的是进程组,但我实际上并不确定这一点,所以我认为安全总比抱歉好。如果你只想试试os.setpgrp(),你可以试试。如果可行,您实际上可以spawn/subprocess/etc。孩子,然后只需setpgid(pid, pid)就可以了。


    同时,听起来您只是 forking 一个孩子并在该孩子中继续执行相同的脚本,在这种情况下,您可以在 fork 之后添加 setsid(或者可能是 setpgrp)你应该完成了。

    【讨论】:

    • 我尝试了类似的方法(但没有成功),请参阅gist.github.com/RedHatter/8264094 这会做同样的事情吗?
    • 是的,应该可以;不知道为什么不。您可能需要同步某些东西,以便父母可以等待孩子在退出之前分离?
    • 嗯...我不太确定该怎么做。
    • 我在父级退出之前添加了一个 sleep 语句,但它并没有改变任何东西。因此我不认为这是一个同步问题。
    • 这在 OSX 上不起作用,使用 .Net 项目调用一个进程,该进程是一个生成子进程的 python 文件。 C# 代码中的 WaitForExit 永远挂起,直到分叉的子进程退出。
    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多