我有一个使用fork()
创建子进程的程序。我已经看到了各种使用wait()
等待子进程在结束前结束的示例,但我想知道如何才能检查文件进程是否仍在运行。
我基本上有一个无限循环,我想做类似的事情:
if(child process has ended) break;
我怎么能这样做?
答案 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
。