Domanda

Questo sarebbe facile con fork (), ma non c'ho MMU. Ho sentito che i blocchi di vfork () il processo padre fino a quando le uscite bambino o esegue exec (). Come faccio a realizzare qualcosa di simile:?

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.....
È stato utile?

Soluzione

Sembra che ci sia alcun modo per farlo esattamente come lo avete qui. exec o _exit devono ottenere chiamato per il genitore di continuare l'esecuzione. O mettere il codice daemon in un altro eseguibile e exec, o usare il bambino per deporre le uova il compito originale. Il secondo approccio è il modo subdolo, ed è descritto qui.

Altri suggerimenti

Funzione

daemon () per sistemi uCLinux senza MMU e forcella ( ), da Jamie Lokier, in formato di patch

Non si può fare daemon () con vfork (). Per creare qualcosa di simile a un demone su! MMU utilizza vfork (), il processo padre non muore (quindi non ci sono processi in più), e si dovrebbe chiamare il demone sullo sfondo (cioè aggiungendo & alla riga di comando sul shell).

D'altra parte, Linux fornisce clone (). Armati di che, la conoscenza e la cura, è possibile implementare daemon () per! MMU. Jamie Lokier ha una funzione di fare proprio questo su ARM e i386, a farla da qui .

Modifica:!. fatto il link al daemon di Jamie Lokier () per MMU Linux più prominente

avrei pensato che questo sarebbe il tipo di problema che molti altri avevano incontrato prima, ma ho avuto un momento difficile trovare qualcuno a parlare di "uccidere il genitore" problemi.

ho inizialmente pensato che si dovrebbe essere in grado di fare questo con un (non così, ma una sorta di) semplice chiamata al clone, in questo modo:

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 */
}

Se non fosse che la determinazione della child_stack e la child_func di lavorare il modo in cui lo fa con vfork è piuttosto difficile poiché child_func avrebbe bisogno di essere l'indirizzo di ritorno dalla chiamata clone e il child_stack avrebbe bisogno di essere in cima alla pila al punto che la chiamata di sistema effettivo (sys_clone) è realizzato.

Si potrebbe forse provare a chiamare sys_clone direttamente con

pid_t new_vfork(void) {
    return sys_clone( SIGCHLD | CLONE_VM, NULL);
}

Il che credo possa ottenere quello che vuoi. Passando NULL come secondo argomento, che è il puntatore child_stack, fa sì che il kernel di fare la stessa cosa come avviene in vfork e forchetta, che è quello di utilizzare lo stesso stack come il genitore.

Non ho mai usato sys_clone direttamente e non hanno testato questo, ma penso che dovrebbe funzionare. Credo che:

  sys_clone( SIGCHLD | CLONE_VM | CLONE_VFORK, NULL);

è equivalente a vfork.

Se questo non funziona (e non si può capire come fare qualcosa di simile), allora potreste essere in grado di utilizzare la chiamata clone di regolare con chiamate setjump e longjmp di emularlo, o si può essere in grado di andare in giro la necessità di "due volte di ritorno" semantica del di fork e vfork.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top