如何使用vfork在uClinux中生成守护进程?

时间:2010-10-08 18:29:31

标签: c linux fork 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.....

3 个答案:

答案 0 :(得分:3)

似乎没有办法像你在这里完全一样。必须调用exec_exit以便父级继续执行。将守护进程代码放入另一个可执行文件并exec,或者使用子进程生成原始任务。第二种方法是偷偷摸摸的方式,并在这里描述。

答案 1 :(得分:3)

daemon() function for uClinux systems without MMU and fork(), by Jamie Lokier, in patch format

你不能用vfork()做守护进程()。要使用vfork()在MMU上创建类似于守护进程的东西,父进程不会死(因此有额外的进程),你应该在后台调用你的守护进程(即通过在命令行中附加&)壳)。

另一方面,Linux提供clone()。有了这些,知识和关心,就可以为!MMU实现守护进程()。 Jamie Lokier可以在ARM和i386上实现这一功能,从here获取。

编辑:为Jamie Lokier的守护进程()提供了链接!MMU Linux更为突出。

答案 2 :(得分:1)

我原本以为这会是许多其他人之前遇到过的问题,但我很难找到有人谈论“杀死父母”的问题。

我最初认为你应该能够通过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需要是克隆调用的返回地址,而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

如果这不起作用(你无法弄清楚如何做类似的事情),那么你可以使用常规克隆调用以及setjumplongjmp调用来模拟它,或者你可能能够满足forkvfork的“返回两次”语义的需要。