2010-10-08 5 views
3

Это было бы легко с fork(), но у меня нет MMU. Я слышал, что vfork() блокирует родительский процесс, пока ребенок не выйдет или не выполнит exec(). Как бы я сделать что-то вроде этого ?:Как мне создать демона в uClinux с помощью vfork?

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

Кажется, нет никакого способа сделать это именно так, как вы его здесь. exec или _exit необходимо вызвать для родителя, чтобы продолжить выполнение. Либо поставьте код демона в другой исполняемый файл и exec, либо используйте дочерний элемент для создания исходной задачи. Второй подход - подлый подход и описан здесь.

+0

Нижняя часть была незаслуженной. Здав прав. – ninjalj

+0

Твист заключается в использовании двоичного кода с несколькими вызовами, тогда вам не нужно вводить двоичный код в другой исполняемый файл. –

+0

Я считаю, что URL должен быть http://www.ucdot.org/article.pl?sid=03/12/12/0317219&mode=thread – ninjalj

3

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

Вы не можете сделать демон() с vfork(). Чтобы создать что-то похожее на демон на MMU, используя vfork(), родительский процесс не умирает (поэтому есть дополнительные процессы), и вы должны называть своего демона фоновым (например, добавив & в командную строку на оболочка).

С другой стороны, Linux предоставляет клон(). Вооружившись этим, знания и забота, возможно реализовать демон() для! MMU. У Джейми Локье есть функция, чтобы сделать это на ARM и i386, получить его от here.

Редактировать: ссылка на демон Джейми Локье() для! MMU Linux более заметным.

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 должен быть обратным адресом от вызова clone, а 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.

+0

Интересно, будет ли это страдать от описанной здесь проблемы: http: // www .mail-archive.com/uclinux-dev @ uclinux.org/msg01290.html – ninjalj

+0

Возможно, будет. Кроме того, мне не удалось найти библиотечную функцию 'sys_clone'. Конечно, было бы неплохо иметь. – nategoose

 Смежные вопросы

  • Нет связанных вопросов^_^