2009-10-24 12 views
11

Zrobiłem fork i exec() na procesie, ale chciałbym uruchomić go w tle. Jak mogę to zrobić? Mogę po prostu uniknąć wywoływania waitpid na tym, ale wtedy proces siedzi tam na zawsze, czekając na przywrócenie statusu rodzicowi. Czy jest jakiś inny sposób na zrobienie tego?Jak wykonać exec() proces w tle w C?

Odpowiedz

5

Złap SIGCHLD i w programie obsługi wywołaj wait().

Niektóre smaki Posixa (myślę, że * BSD, ale nie cytuj mnie), jeśli zignorujesz SIGCHLD, jądro automatycznie oczyści proces zombie (co widzisz w ps). To fajna funkcja, ale nie przenośna.

+0

To było najczystsze rozwiązanie do wdrożenia. Dzięki! –

+0

Dla przyszłych programistów z tym samym pytaniem, oto co znalazłem na stronie 293 w "Programowaniu zaawansowanym w środowisku UNIX": SIGCHLD Ilekroć proces kończy się lub kończy, sygnał SIGCHLD jest wysyłany do rodzica. Domyślnie ten sygnał jest ignorowany, więc rodzic musi złapać ten sygnał, jeśli chce być powiadamiany za każdym razem, gdy zmienia się status dziecka. Normalnym działaniem w funkcji przechwytywania sygnałów jest wywołanie jednej z funkcji oczekiwania w celu pobrania identyfikatora procesu i stanu zakończenia dziecka. W tym przypadku potrzebowałem linii takiej jak liw.fi zasugerował: waitpid (-1, & status, WNOHANG | WUNTRACED); –

-1

Widelec do utworzenia wątku tła, a następnie exec. Zobacz pytanie dotyczące dupe na tej stronie: Can we start a background process using exec() giving & as an argument?

+0

Tak, widziałem to pytanie, ale nadal nie odpowiada na moje oryginalne pytanie. Pewnie, że mogę uniknąć połączenia oczekującego, ale wtedy proces jest tam na zawsze. Widzę to za każdym razem, gdy uruchamiam ps -al. –

+0

Nie sądzę, że odpowiedzi na poprzednie pytanie rzeczywiście odpowiadają na to pytanie (jak również aditya narzeka); poprawna odpowiedź została udzielona przez Avi. Ponadto sceptycznie podchodzę do tego, że odpowiedzi na poprzednie pytanie faktycznie odpowiadają na to pytanie (ponieważ OP chciał również stworzyć proces w tle i nikt nie powiedział mu o podwójnym rozwidleniu). –

0

waitpid(-1, &status, WNOHANG) może zrobić to, czego potrzebujesz: powinien natychmiast wrócić, jeśli proces potomny nie zakończył działania. Alternatywnie możesz posłuchać sygnału SIGCHLD.

+0

To nie jest dobra strategia - chyba że proces nadrzędny jest gotowy to robić w kółko (w przeciwnym razie nadal będziesz zombie). –

+0

Niestety uzyskałem dokładnie taki wynik, jaki przewidział Martin, ale z pewnością brzmiało to dobrze do tego czasu. –

+0

Wszystko zależy od struktury struktury nadrzędnej. Czasami łatwiej jest sondować sporadycznie, niż łapać SIGCHLD. –

4

Myślę, że to, co próbujesz zrobić, to stworzyć proces demona. Przeczytaj link o Wikipedii pod adresem this.

Przykład (z zaawansowanego programowania Stevena w Unix Środowiska), a także proces demon brzmi:

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int daemon_int(void) 
{ 
    pid_t pid; 
    if ((pid = fork()) < 0) 
     return (-1) ; 
    else if (pid != 0) 
     exit(0) ; /* The parent process exits */ 
    setsid() ; /* become session leader */ 
    chdir("/") ; /* change the working dir */ 
    umask(0) ; /* clear out the file mode creation mask */ 
    return(0) ; 
} 

Oczywiście to nie zakładamy Unix jak OS.

Twój program zawiera powyższą funkcję i wywołuje ją zaraz po uruchomieniu. Jest to następnie dyskalkowane z procesu nadrzędnego i będzie po prostu działało, dopóki nie zakończy się lub zostanie zabite.

+0

Hmm bliższe zapoznanie się z pytaniem sprawia, że ​​myślę, że Avi może mieć odpowiedź. Lub możesz spowodować, że pierwsze dziecko stanie się demonem, który czeka na zakończenie Wnuka. Tak więc zerwij połączenie między rodzicem i dzieckiem, aby rodzic mógł zakończyć, nie powodując wyjścia dziecka i wnuka. – Jackson

+0

Jeśli chcesz to zrobić, chcesz również, aby oryginalny proces wywoływał funkcję wait(), aby pobrać dziecko. Ponieważ proces potomny szybko się zakończy (zaraz po rozwidleniu wnuka), twój oryginalny proces nie zablokuje długiego oczekiwania(). –

Powiązane problemy