在 C++ 中检查子进程的状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5278582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Checking the status of a child process in C++
提问by Alex
I have a program that uses fork()
to create a child process. I have seen various examples that use wait()
to wait for the child process to end before closing, but I am wondering what I can do to simply check if the file process is still running.
我有一个fork()
用于创建子进程的程序。我见过各种wait()
用于在关闭之前等待子进程结束的示例,但我想知道我可以做些什么来简单地检查文件进程是否仍在运行。
I basically have an infinite loop and I want to do something like:
我基本上有一个无限循环,我想做一些类似的事情:
if(child process has ended) break;
if(child process has ended) break;
How could I go about doing this?
我怎么能去做这件事?
回答by Erik
Use waitpid()
with the WNOHANG
option.
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
}
回答by Gabe
You don't need to wait for a child until you get the SIGCHLD
signal. If you've gotten that signal, you can call wait
and see if it's the child process you're looking for. If you haven't gotten the signal, the child is still running.
在收到SIGCHLD
信号之前,您无需等待孩子。如果你得到了那个信号,你可以打电话wait
看看它是否是你正在寻找的子进程。如果你还没有收到信号,那孩子还在跑。
Obviously, if you need to do nothing unitl the child finishes, just call wait
.
显然,如果您在孩子完成之前不需要做任何事情,只需调用wait
.
回答by Alexander Kondratskiy
EDIT:If you just want to know if the child process stopped running, then the other answers are probably better. Mine is more to do with synchronizing when a process could do several computations, without necessarily terminating.
编辑:如果您只想知道子进程是否停止运行,那么其他答案可能会更好。我的更多是在进程可以进行多次计算时进行同步,而不必终止。
If you have some object representing the child computation, add a method such as bool isFinished()
which would return true if the child has finished. Have a private bool member in the object that represents whether the operation has finished. Finally, have another method private setFinished(bool)
on the same object that your child process calls when it finishes its computation.
如果您有一些表示子计算的对象,请添加一个方法,例如,bool isFinished()
如果子计算完成,该方法将返回 true。对象中有一个私有的 bool 成员,表示操作是否已完成。最后,setFinished(bool)
在子进程完成计算时调用的同一对象上有另一个私有方法。
Now the most important thing is mutex locks. Make sure you have a per-object mutex that you lock every time you try to access any members, including inside the bool isFinished()
and setFinished(bool)
methods.
现在最重要的是互斥锁。确保您有一个每个对象的互斥锁,每次尝试访问任何成员时都会锁定该互斥锁,包括在bool isFinished()
和setFinished(bool)
方法内部。
EDIT2:(some OO clarifications)
EDIT2:(一些面向对象的说明)
Since I was asked to explain how this could be done with OO, I'll give a few suggestions, although it heavily depends on the overall problem, so take this with a mound of salt. Having most of the program written in C style, with one object floating around is inconsistent.
由于我被要求解释如何使用 OO 来完成此操作,因此我将给出一些建议,尽管这在很大程度上取决于整体问题,因此请多加注意。大部分程序都是用 C 风格编写的,一个对象漂浮在周围是不一致的。
As a simple example you could have a class called ChildComputation
作为一个简单的例子,你可以有一个名为 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
}
Now in your main program, where you fork:
现在在你的主程序中,你分叉的地方:
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;
}
Hope that makes sense.
希望这是有道理的。
To reiterate, what I have written above is an ugly amalgamation of C and C++(not in terms of syntax, but style/design), and is just there to give you a glimpse of synchronization with OO, in your context.
重申一下,我上面写的是C 和 C++的丑陋合并(不是在语法方面,而是在风格/设计方面),只是为了让您在您的上下文中一瞥与 OO 的同步。