在 C 中检查子进程的状态

新手上路,请多包涵

我有一个程序使用 fork() 创建一个子进程。我已经看到了各种使用 wait() 等待子进程在关闭之前结束的示例,但我想知道我可以做些什么来简单地检查文件进程是否仍在运行。

我基本上有一个无限循环,我想做类似的事情:

if(child process has ended) break;

我怎么能这样做呢?

原文由 Alex 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 670
2 个回答

waitpid()WNOHANG 选项一起使用。

 int status;
pid_t result = waitpid(ChildPID, &status, WNOHANG);
if (result == 0) {
  // Child still alive
} else if (result == -1) {
  // Error
} else {
  // Child exited
}

原文由 Erik 发布,翻译遵循 CC BY-SA 2.5 许可协议

编辑: 如果您只想知道子进程是否停止运行,那么其他答案可能会更好。当一个进程可以进行多次计算时,我的更多是与同步有关,而不必终止。

如果您有一些代表子计算的对象,请添加一个方法,例如 bool isFinished() 如果子计算完成,它将返回 true。在表示操作是否完成的对象中有一个私有的 bool 成员。最后,在子进程完成计算时调用的同一个对象上使用另一个私有方法 setFinished(bool)

现在最重要的是 _互斥锁_。确保每次尝试访问任何成员时都锁定了每个对象的互斥锁,包括在 bool isFinished()setFinished(bool) 方法中。

EDIT2:( 一些OO澄清)

由于我被要求解释如何使用 OO 完成此操作,因此我将给出一些建议,尽管这在 _很大程度上取决于整体问题_,因此请多加注意。大部分程序都是用 C 风格编写的,只有一个对象浮动是不一致的。

作为一个简单的例子,你可以有一个名为 ChildComputation 的类

class ChildComputation {

    public:
    //constructor
    ChildComputation(/*some params to differentiate each child's computation*/) :
        // populate internal members here {
    }
    ~ChildComputation();

    public:
    bool isFinished() {
        m_isFinished; // no need to lock mutex here, since we are not modifying data
    }

    void doComputation() {
        // put code here for your child to execute
        this->setFinished(true);
    }

    private:
    void setFinished(bool finished) {
        m_mutex.lock();
        m_isFinished = finished;
        m_mutex.unlock();
    }

    private:
    // class members
    mutex m_mutexLock; // replace mutex with whatever mutex you are working with
    bool m_isFinished;
    // other stuff needed for computation
}

现在在你的主程序中,你在哪里分叉:

 ChildComputation* myChild = new ChildComputation(/*params*/);
ChildPID= fork();
if (ChildPID == 0) {
   // will do the computation and automatically set its finish flag.
   myChild->doComputation();
}
else {
   while (1) { // your infinite loop in the parent
       // ...

       // check if child completed its computation
       if (myChild->isFinished()) {
           break;
       }
   }

   // at the end, make sure the child is no runnning, and dispose of the object
   // when you don't need it.
   wait(ChildPID);
   delete myChild;
}

希望这是有道理的。

重申 一下,我上面写的是 C 和 C++ 的丑陋融合(不是在语法方面,而是在风格/设计方面),只是为了让您在您的上下文中了解与 OO 的同步。

原文由 Alexander Kondratskiy 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题