2009-06-16 8 views
14

Ich möchte einen Prozess aus meinem c-Programm starten, aber ich möchte nicht warten, bis das Programm beendet ist. Ich kann diesen Prozess mit System() starten, aber das System wartet immer. Kennt jemand eine "nicht blockierende" Version, die zurückkehrt, sobald der Prozess gestartet wurde?Nicht blockierende Version des Systems()

[Bearbeiten - Zusätzliche Anforderung] Wenn der ursprüngliche Prozess ausgeführt wurde, muss der untergeordnete Prozess weiter ausgeführt werden.

+0

Ich dachte 'system()' war nicht blockierend. – puk

Antwort

14

Warum nicht fork() und exec() verwenden und einfach nicht waitpid() anrufen?

Zum Beispiel könnten Sie wie folgt vorgehen:

// ... your app code goes here ... 
pid = fork(); 
if(pid < 0) 
    // error out here! 
if(!pid && execvp(/* process name, args, etc. */) 
    // error in the child proc here! 
// ...parent execution continues here... 
+0

hmmm, scheint nicht für mich zu arbeiten. Ich denke, das Problem könnte sein, dass mein Programm (es ist eine CGI-App) existiert, sobald es execvp heißt - wird das den Kindprozess beenden? Auch ... der Code nach Execvp scheint zweimal ausgeführt zu werden. –

+0

Simon, kannst du hier ein Codebeispiel platzieren? Was passieren könnte, ist, dass der Elternteil beendet wird, sobald der Kindprozess gespalten wurde. Haben Sie waitpid (chld_pid) wie von Herrn/Frau vorgeschlagen verwendet? Freier Speicher? – SashaN

+0

@Simon: Wenn der Code nach execvp() scheinbar doppelt ausgeführt wird, bedeutet dies höchstwahrscheinlich, dass die execvp() -Funktion fehlgeschlagen ist und die Fehlerbehandlung für sie nicht die Ausführung von Fehlern (Rückkehr oder Beenden) verhindert hat. Kennen Sie in einem CGI-Programm, auf was der PATH eingestellt ist? Es ist wahrscheinlich spartanischer als Sie erwartet haben. –

15

Eine Option in Ihrem Systemaufruf ist, dies zu tun:

system("ls -l &"); 

die & am Ende der Befehlszeilenargumente die Gabeln Aufgabe, die Sie gestartet haben.

6

Der normale Weg, es zu tun, und tatsächlich sollten Sie system() nicht mehr verwenden, ist popen.
Auf diese Weise können Sie auch

Bearbeiten aus dem erzeugten Prozess stdin/heraus lesen oder schreiben: Siehe popen2(), wenn Sie lesen und schreiben müssen - thansk quinmars

+0

Ich denke, das sollte gelesen werden _oder_ schreiben – quinmars

0

Am Ende dieser Code scheint zu funktionieren . Bit eines Fehl Maische der oben genannten Antworten:

pid = fork(); 

if (!pid) 
{ 
    system("command here &"); 
} 

exit(0); 

Nicht ganz sicher, warum es funktioniert, aber es tut, was ich nach vielen Dank an alle für Ihre Hilfe

+0

Es funktioniert, aber es ist nicht wirklich das, was Sie tun möchten. system() forkiert tatsächlich eine Instanz einer Shell und übergibt der Shell den Befehl, den Sie ausführen möchten. Also, was Sie tun, ist im Wesentlichen wie folgt: fork(), fork(), execl ("/ bin", "sh", "command_to_run &"). Sicher, es funktioniert, aber es macht viel mehr Arbeit, als es sollte. – FreeMemory

+0

warum die zusätzliche Gabel()? Kannst du nicht einfach das System benutzen ("... &"); Anruf? –

1

Sie könnten posix_spawnp verwenden() Funktion. Es ist ähnlich wie system() als die Kombination aus fork und exec *, aber nicht blockierend.

Verwandte Themen