如何使用 vfork 在 uClinux 中生成守护进程?
这对于 fork() 来说很容易,但我没有 MMU。我听说 vfork() 会阻止父进程,直到子进程退出或执行 exec()。我将如何完成这样的事情?:
pid_t pid = vfork();
if (pid == -1) {
// fail
exit(-1);
}
if (pid == 0) {
// child
while(1) {
// Do my daemon stuff
}
// Let's pretend it exits sometime
exit();
}
// Continue execution in parent without blocking.....
This would be easy with fork(), but I've got no MMU. I've heard that vfork() blocks the parent process until the child exits or executes exec(). How would I accomplish something like this?:
pid_t pid = vfork();
if (pid == -1) {
// fail
exit(-1);
}
if (pid == 0) {
// child
while(1) {
// Do my daemon stuff
}
// Let's pretend it exits sometime
exit();
}
// Continue execution in parent without blocking.....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
似乎没有办法完全像你在这里那样做到这一点。必须调用
exec
或_exit
父级才能继续执行。将守护程序代码放入另一个可执行文件中并执行它,或者使用子进程生成原始任务。第二种方法是偷偷摸摸的方法,在这里进行了描述。It seems there is no way to do this exactly as you have it here.
exec
or_exit
have to get called for the parent to continue execution. Either put the daemon code into another executable andexec
it, or use the child to spawn the original task. The second approach is the sneaky way, and is described here.daemon() 函数用于没有 MMU 和 fork() 的 uClinux 系统,通过Jamie Lokier,补丁格式
您不能使用 vfork() 执行 daemon()。要使用 vfork() 在 !MMU 上创建类似于守护进程的东西,父进程不会终止(因此有额外的进程),并且您应该在后台调用您的守护进程(即通过将 & 附加到命令行上外壳)。
另一方面,Linux提供了clone()。有了这些、知识和细心,就有可能为 !MMU 实现 daemon() 。 Jamie Lokier 有一个函数可以在 ARM 和 i386 上执行此操作,从
编辑:使 !MMU Linux 的 Jamie Lokier daemon() 链接更加突出。
daemon() function for uClinux systems without MMU and fork(), by Jamie Lokier, in patch format
You can't do daemon() with vfork(). To create something similar to a daemon on !MMU using vfork(), the parent process doesn't die (so there are extra processes), and you should call your daemon on the background (i.e. by appending & to the command line on the shell).
On the other hand, Linux provides clone(). Armed with that, knowledge and care, it's possible to implement daemon() for !MMU. Jamie Lokier has a function to do just that on ARM and i386, get it from here.
Edit: made the link to Jamie Lokier's daemon() for !MMU Linux more prominent.
我本以为这将是许多其他人以前遇到过的问题类型,但我很难找到任何人谈论“杀死父母”问题。
我最初认为您应该能够通过(不完全如此,但有点)简单地调用
clone
来完成此操作,如下所示:除了确定 child_stack 和 child_func 的工作方式之外使用 vfork 做到这一点非常困难,因为 child_func 需要是克隆调用的返回地址,而 child_stack 需要是实际系统调用(sys_clone)进行时的堆栈顶部。
您可能可以尝试直接调用
sys_clone
,我认为这可能会得到您想要的。传递 NULL 作为第二个参数(即 child_stack 指针)会导致内核执行与 vfork 和 fork 中相同的操作,即使用与父级相同的堆栈。
我从未直接使用过 sys_clone ,也没有测试过它,但我认为它应该可以工作。我相信:
相当于vfork。
如果这不起作用(并且您不知道如何执行类似的操作),那么您可以将常规克隆调用与
setjump
和longjmp
一起使用调用来模拟它,或者您也许能够避免对fork
和vfork
的“返回两次”语义的需要。I would have thought that this would be the type of problem that many others had run into before, but I've had a hard time finding anyone talking about the "kill the parent" problems.
I initially thought that you should be able to do this with a (not quite so, but sort of) simple call to
clone
, like this:Except that determining the child_stack and the child_func to work the way that it does with vfork is pretty difficult since child_func would need to be the return address from the clone call and the child_stack would need to be the top of the stack at the point that the actual system call (sys_clone) is made.
You could probably try to call
sys_clone
directly withWhich I think might get what you want. Passing NULL as the second argument, which is the child_stack pointer, causes the kernel to do the same thing as it does in vfork and fork, which is to use the same stack as the parent.
I've never used
sys_clone
directly and haven't tested this, but I think it should work. I believe that:is equivalent to
vfork
.If this doesn't work (and you can't figure out how to do something similar) then you may be able to use the regular clone call along with
setjump
andlongjmp
calls to emulate it, or you may be able to get around the need for the "return's twice" semantics offork
andvfork
.