2013-02-12 19 views
14

erscheint Es läuft eine externe ausführbare Datei von C in Unix zwei gemeinsamen Wegen zu sein, deran system() oder fork()/exec()?

system() 

Anruf und

pid = fork() 
switch(pid) 
//switch statement based on return value of pid, 
//one branch of which will include and exec() command 

Gibt es einen Grund, einen fork/exec über System in der bevorzugen Fall, in dem sie funktional gleichwertig sind (der Elternprozess wartet, bis das Kind fertig ist, es werden keine komplexen Informationen vom Kind zurückgegeben)?

Antwort

18

system führt einen Befehlsinterpreter aus, dh eine Shell, die (a) langsamer ist als ein direkter Fork/Exec, (b) sich auf verschiedenen Systemen anders verhalten kann und (c) ein potenzielles Sicherheitsrisiko darstellt, wenn Sie es übergeben eine Zeichenfolge aus einer nicht vertrauenswürdigen Quelle. Außerdem wartet system darauf, dass der untergeordnete Prozess beendet wird, während Sie möglicherweise möchten, dass er gleichzeitig mit dem übergeordneten Prozess ausgeführt wird.

Mehr im Allgemeinen, die Low-Level-fork/exec gibt Ihnen zusätzliche Kontrolle: vor oder zwischen den beiden Operationen, die Sie chdir wollen könnten, offene Rohre, in der Nähe Filedeskriptoren, einrichten gemeinsam genutzten Speicher usw.

(Mit verschiedenen Systemen meine ich nicht Windows vs. Unix (da Windows nicht einmal fork hat): Ich spreche Red Hat Linux vs. Ubuntu. Der ehemalige verwendet Bash um auszuführen, was an system übergeben wird, Letzteres ist eine leichtgewichtige POSIX-kompatible Shell.)

+0

Ich fragte meinen Professor, was der Unterschied ist und er sagte 'System()' ist eine API für das Betriebssystem und 'fork/exec' sind Aufrufe auf Systemebene. Ist das wahr? Nach meinem Verständnis sind APIs für das Betriebssystem sicherer, da sie im Gegensatz zu Systemaufrufen zusätzliche Prüfungen enthalten können. – Celeritas

+2

@Celeritas In gewissem Sinne (Systemaufrufe sind OS APIs auch), aber Ihre Schlussfolgerung ist falsch, wie ich in der Antwort argumentiert habe. 'system' fügt keine Schecks hinzu; es fügt unchecked Funktionalität hinzu. –

0

system() gibt den Befehl aus und führt ihn wie ein Benutzer aus. ich sah es meistens wie system("pause"); system("cls");

Aber wenn Sie den untergeordneten Prozess steuern möchten, möchten Sie verzweigen.

+5

'System (" Pause ");' ist eine Krankheit! Es ist die ineffizienteste Methode, das Programm darauf zu warten, dass der Benutzer etwas eingibt. –

+0

@JohnZwinck es war gut genug für das College :) war in der Regel dort, um die Konsole "dort zu bleiben", wenn das Programm zu beenden ist. – Shark

+1

Beim nächsten Mal versuchen Sie etwas wie 'cin >> dummy;' (oder scanf()). Und denken Sie nicht, dass Arbeit höhere Standards hat als Schule! –

1

Wenn Sie über system() gehen, wird zusätzlich ein Shell-Prozess aufgerufen, der möglicherweise nicht Ihren Vorstellungen entspricht.

Auch der aufrufende Prozess wird nur benachrichtigt, wenn eine solche Shell nicht stirbt, wenn der eigentliche Prozess von der Shell abgestürzt ist.

3

fork() erstellt einen neuen Prozess. Wenn Sie dies nicht tun müssen, verwenden Sie einfach system() (oder popen()). Vielleicht möchten Sie einen zweiten Prozess, um Parallelität zu erreichen, oder für eine feinere Kontrolle über den Job, aber oft ist es Ihnen egal, ob der Job synchron sein soll.

Auf der anderen Seite, finde ich, dass 95% der Verwendungen von system() sind unnötig oder würde irgendwie besser aus einem anderen Weg getan werden (z. B. mit zlib anstelle von system("gzip")). Also die beste Antwort ist vielleicht, keine zu verwenden!

+0

In diesem Fall ist es ein benutzerdefiniertes Tool, das von jemand anderem erstellt wurde, also muss ich entweder den Code in eine Bibliothek umwandeln, über sys oder exec aufrufen oder einen Teil der Quelle in meine eigenen Binärdateien kopieren. Es ist eine knifflige Wahl zwischen der Geschwindigkeit der Wartbarkeit der Implementierung. – Sparky

+1

Nur der Vollständigkeit halber gibt es noch eine weitere Möglichkeit: Verwenden Sie eine höhere Programmiersprache wie Python, um dieses Tool von Drittanbietern aufzurufen, und dienen Sie auch als "main()" für Ihren eigenen Code. Stellen Sie also Ihre eigene Logik als Bibliothek oder ausführbare Datei zur Verfügung und verwenden Sie ein Skript, um die Teile miteinander zu verbinden, anstatt von C. wegzuschmeißen. Denkanstoß. –

+2

Sowohl system() als auch popen() erzeugen zwei neue Prozesse - einen für die Shell und einen weiteren für den Befehl, der innerhalb der Shell ausgeführt wird. – pelya

Verwandte Themen