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

C++ 在C+中检查子进程的状态+;,c++,fork,parent,wait,C++,Fork,Parent,Wait,我有一个使用fork()创建子进程的程序。我看到了各种使用wait()等待子进程结束再关闭的示例,但我想知道我可以做些什么来简单地检查文件进程是否仍在运行 我基本上有一个无限循环,我想做如下事情: 如果(子进程已结束)中断 我怎样才能这样做呢?使用waitpid()和WNOHANG选项 int status; pid_t result = waitpid(ChildPID, &status, WNOHANG); if (result == 0) { // Child still al

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

我基本上有一个无限循环,我想做如下事情:

如果(子进程已结束)中断

我怎样才能这样做呢?

使用
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
}

您不需要等待孩子,直到收到
SIGCHLD
信号。如果您收到了该信号,您可以调用
wait
,查看是否是您正在寻找的子进程。如果你没有收到信号,孩子还在跑


显然,如果在子进程完成之前不需要执行任何操作,只需调用
wait

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

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

我不确定如何确切地将我的子进程变成一个对象。这是我第一次做这种类型的编程,所以我的理解还是相当基本的。现在我有一个main函数,它创建两个管道,然后分叉,还有一个if-else语句,使用pid来分隔父进程和子进程的代码。我怎么能做这个面向对象的?如果你的问题很简单,也许你甚至不需要把它变成OO,我只是假设你把C++作为标签。这实际上取决于你试图解决的总体问题。Erik的答案最适合您当前的代码。不过,我会在我的答案中添加一些东西来澄清。这是有道理的。我认为这比C++问题更像是一个C问题。我只是习惯于使用C++和AM,在我的程序中包含一些C++函数,但是程序的这一部分确实更像C。我想将来我会给它贴上C/C++。我怎么知道我是否得到了那个信号?所以ChildPID是我用来区分父级和子级的,结果是一个新的pid,它生成一个新的子进程,监视子进程退出?不,ChildPID是
fork()
返回的子进程的进程ID
waitpid()
只是一个返回值的函数:
0
ChildPid
-1
,我的意思是我做了一个
pid\u t
来表示
pid=fork()。现在要为父进程和子进程编写代码,我有一个if-else,它检查
if(pid)
以识别父进程,因为在父进程中
pid
包含子进程的pid编号,而在子进程中
pid
包含
0
。因此,如果我理解正确,我认为我应该使用
pid
,您说过要使用
ChildPID
@Alex:是的,您的
pid
是子进程的进程ID。您需要使用getpid()来获取子进程的进程ID。使用-1代替childpid将有效