【问题标题】:telling when an execl() process exits告诉 execl() 进程何时退出
【发布时间】:2010-11-02 18:14:09
【问题描述】:

我有一个 C++ 应用程序,其中包含队列中的某些项目,然后这些项目将由 python 脚本处理。我希望它最多运行 10 个 python 脚本实例。我打算使用 execl() 来启动 python 进程,有没有办法告诉进程已经退出而不必将消息传递回父进程?

【问题讨论】:

    标签: c++ unix os.execl


    【解决方案1】:

    execl 不启动进程——它用另一个可执行文件覆盖现有进程。 fork 确实启动了一个进程——并将子进程的 id(又名pid)返回给父进程(返回 0 给子进程,这就是子进程知道它是子进程的方式,所以它可以清理东西和exec)。使用孩子们的pids 来检查他们是否完成了,或者诱捕SIGCHLD 来跟踪。

    我推荐SIGCHLD,这样您就不必“轮询”来查看某个进程是否已终止,但后一种方法也不太难——只需偶尔执行一次即可:

    def whosdone(pids):
        nope = []
        done = []
        for pid in pids:
            try: os.kill(pid, 0)
            except OSError: nope.append(pid)
            else: done.append(pid)
        return done, nope
    

    即您可以定期致电done, pidslist = whosdone(pidslist) 并对已完成的 PID 做任何您需要做的事情。当然,当你fork时,使用成语:

    pid = os.fork()
    if pid: # we're the parent process
      pidslist.append(pid)
    else:   # we're the child process
      # clean things up, etc, then exec
    

    【讨论】:

    • 您能否详细说明如何检查孩子的 pid 以检查他们是否完成?我不明白这将如何告诉我他们是否完成了
    • os.kill(pid, 0) 如果进程 pid 已终止(或由另一个用户拥有),则会引发 OSError 异常,如果 pid 正在为当前用户运行,则不会出现异常 - 没有其他影响。在那里,让我编辑我的答案...
    • 使用os.wait(0, os.WNOHANG)不是更好吗?这将收获子进程,消除资源泄漏,并避免遍历每个子进程。
    • @bdonlan,我认为您的意思是 os.waitpid(-1, os.WNOHANG) [-1 忽略进程组问题],如果进程没有,那也可以产生其他它不关心的孩子。但是 SIGCHLD 仍然更好(我在上面给出了它的维基百科 URL)并且可以与 .wait 或 .waitpit 配对。
    【解决方案2】:

    如果您在 unix/linux 下的 C++ 中执行此操作,请查看 wait(), waitpid(), waitid()wait3(), or wait4()。您可以调用 waitpid() NOHANG(轮询)或让它阻塞直到子进程完成。 pid(process-id)是fork().返回的值

    I did a painful "hard way" example of fork() earlier (using dup2() to re-route IO).

    【讨论】:

      猜你喜欢
      • 2019-01-02
      • 2010-09-21
      • 2010-10-09
      • 2022-11-10
      • 2013-05-26
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多