在C ++中检查子进程的状态

时间:2011-03-11 21:29:54

标签: c++ fork parent wait

我有一个使用fork()创建子进程的程序。我已经看到了各种使用wait()等待子进程在结束前结束的示例,但我想知道如何才能检查文件进程是否仍在运行。

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

if(child process has ended) break;

我怎么能这样做?

3 个答案:

答案 0 :(得分:35)

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
}

答案 1 :(得分:2)

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

如果您有一些表示子计算的对象,请添加bool isFinished()等方法,如果子项已完成,该方法将返回true。在对象中有一个私有bool成员,表示操作是否已完成。最后,在子进程完成计算时调用同一对象上的另一个方法private 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的同步。

答案 2 :(得分:1)

在收到SIGCHLD信号之前,您无需等待孩子。如果你收到了这个信号,你可以拨打wait并查看它是否是你正在寻找的子进程。如果你还没有收到信号,孩子仍在跑步。

显然,如果孩子完成任务,你只需要打电话给wait