检查 C++ 中子进程的状态
我有一个使用 fork()
创建子进程的程序。我见过各种使用 wait()
在关闭之前等待子进程结束的示例,但我想知道我可以做什么来简单地检查文件进程是否仍在运行。
我基本上有一个无限循环,我想做一些类似的事情:
if(child process has goneed) break;
我怎样才能做到这一点?
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.
I basically have an infinite loop and I want to do something like:
if(child process has ended) break;
How could I go about doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
将
waitpid()
与WNOHANG
选项结合使用。Use
waitpid()
with theWNOHANG
option.您无需等待子进程直到收到
SIGCHLD
信号。如果您收到该信号,则可以调用wait
并查看它是否是您正在寻找的子进程。如果你没有收到信号,孩子还在跑。显然,如果您在子进程完成之前不需要执行任何操作,只需调用
wait
即可。You don't need to wait for a child until you get the
SIGCHLD
signal. If you've gotten that signal, you can callwait
and see if it's the child process you're looking for. If you haven't gotten the signal, the child is still running.Obviously, if you need to do nothing unitl the child finishes, just call
wait
.编辑:如果您只想知道子进程是否停止运行,那么其他答案可能更好。我的更多的是与同步有关,当一个进程可以执行多次计算而不必终止时。
如果您有一些代表子计算的对象,请添加一个方法,例如 bool isFinished() ,如果子计算已完成,该方法将返回 true。对象中有一个私有 bool 成员,表示操作是否已完成。最后,在子进程完成计算时调用的同一个对象上有另一个方法 private
setFinished(bool)
。现在最重要的是互斥锁。确保每次尝试访问任何成员时都锁定每个对象的互斥锁,包括在
bool isFinished()
和setFinished(bool)
方法内。编辑2:(一些面向对象的说明)
由于我被要求解释如何使用面向对象来完成此操作,我将给出一些建议,尽管它很大程度上取决于总体问题,所以把它和一堆盐一起服用。大部分程序都是用 C 风格编写的,而一个对象四处浮动是不一致的。
创建一个名为
ChildComputation
的类作为一个简单的例子,您可以在主程序中
,您可以在其中进行分叉:希望这是有道理的。
重申,我上面写的内容是丑陋的 C 和 C++ 合并(不是在语法方面,而是在风格/设计方面),并且只是为了给您提供帮助在您的上下文中了解与 OO 的同步。
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 privatesetFinished(bool)
on the same object that your child process calls when it finishes its computation.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()
andsetFinished(bool)
methods.EDIT2: (some OO clarifications)
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.
As a simple example you could have a class called
ChildComputation
Now in your main program, where you fork:
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++ 中运行? 因为这基本上是重复的。唯一的区别是函数的用例。
使用
kill(pid, sig)
但检查errno
状态。如果您以其他用户身份运行并且无权访问该进程,它将失败并显示 EPERM,但该进程仍然处于活动状态。您应该检查ESRCH,这意味着没有这样的过程
。如果您正在运行子进程,则终止将成功,直到调用
waitpid
为止,这也会强制清理所有已失效的进程。这是一个函数,它返回 true 进程是否仍在运行,并处理清理失效的进程。
I'm posting the same answer here i posted at as this question How to check if a process is running in C++? as this is basically a duplicate. Only difference is the use case of the function.
Use
kill(pid, sig)
but check for theerrno
status. If you're running as a different user and you have no access to the process it will fail with EPERM but the process is still alive. You should be checking for ESRCH which meansNo such process
.If you're running a child process kill will succeed until
waitpid
is called that forces the clean up of any defunct processes as well.Here's a function that returns true whether the process is still running and handles cleans up defunct processes as well.