如何使用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.....
解决方案
似乎没有办法完全像您在这里一样。 exec
或者 _exit
必须要求父母继续执行。要么将守护程序代码放入另一个可执行文件中 exec
它,或使用孩子产生原始任务。第二种方法是偷偷摸摸的方式,在这里进行了描述。
其他提示
jamie lokier的daemon()功能,无MMU和FORK()
您不能使用vfork()进行守护程序()。要使用vfork()创建类似于!mmu上的守护程序的东西,父进程不会死(因此有额外的进程),您应该在背景上调用守护程序(即,通过附加和上的命令行来调用贝壳)。
另一方面,Linux提供clone()。有了知识和关怀,可以为!mmu实施守护程序()。杰米·洛基尔(Jamie Lokier 这里.
编辑: 使杰米·洛基(Jamie Lokier)的守护程序()链接更加突出。
我本来会认为这将是许多其他人以前遇到的问题,但是我很难找到任何人谈论“杀死父母”问题的问题。
我最初以为您应该能够用(不是完全如此,但有点)简单的呼吁来做到这一点 clone
, , 像这样:
pid_t new_vfork(void) {
return clone(child_func, /* child function */
child_stack, /* child stack */
SIGCHLD | CLONE_VM, /* flags */
NULL, /* argument to child */
NULL, /* pid of the child */
NULL, /* thread local storage for child */
NULL); /* thread id of child in child's mem */
}
除了确定child_stack和child_func以与vfork的方式工作非常困难,因为Child_func需要是Clone Call中的返回地址,并且Child_stack需要在堆栈中成为堆栈的顶部。进行实际系统调用(SYS_CLONE)。
您可能可以尝试致电 sys_clone
直接与
pid_t new_vfork(void) {
return sys_clone( SIGCHLD | CLONE_VM, NULL);
}
我认为可能会得到您想要的。将null作为第二个参数(即Child_stack指针)传递,使内核做与vfork和fork中相同的事情,即使用与父母相同的堆栈。
我从未使用过 sys_clone
直接并且没有测试过,但我认为它应该起作用。我相信:
sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);
等同于 vfork
.
如果这不起作用(并且您无法弄清楚如何做类似的事情),那么您可以使用常规克隆调用 setjump
和 longjmp
仿真的呼吁,或者您可能能够满足“返回两次”语义的需求 fork
和 vfork
.