web-dev-qa-db-ja.com

system()またはfork()/ exec()に?

UNIXでCから外部実行可能ファイルを実行する一般的な方法は2つあるようです。

system()

電話して

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

機能的に同等である場合(親プロセスが子の終了を待機し、子から複雑な情報が返されない場合)、システムよりもフォーク/実行を優先する理由はありますか?.

14
Sparky

systemは、コマンドインタープリター、つまりシェルを実行します。これは、(a)ダイレクトフォーク/実行よりも低速であり、(b)システムごとに動作が異なる可能性があり、(c)合格するとセキュリティ上の危険が生じる可能性があります信頼できないソースからの文字列です。また、systemは子プロセスが終了するのを待ちますが、親プロセスと同時に実行したい場合もあります。

より一般的には、低レベルのfork/execを使用すると、追加の制御が可能になります。2つの操作の前または間に、chdir、パイプのオープン、ファイル記述子のクローズ、共有メモリのセットアップなどを行うことができます。

(異なるシステムでは、WindowsとUnixを意味するわけではありません(Windowsにはフォークさえありません):Red Hat LinuxとUbuntuについて話します。前者は、Bashを使用してsystem、後者は軽量のPOSIX互換シェルです。)

19
Fred Foo

fork()は新しいプロセスを作成します。それを行う必要がない場合は、system()(またはpopen())を使用してください。並列処理を実現するため、またはジョブをよりきめ細かく制御するために2番目のプロセスが必要になる場合がありますが、ジョブが同期することを目的としている場合は、それを気にしないことがよくあります。

一方、system()の使用の95%は不要であるか、別の方法(system("gzip")の代わりにzlibを使用するなど)で行う方がよいことがわかりました。したがって、おそらく最善の答えはどちらも使用しないことです!

3
John Zwinck

system()を経由すると、さらにシェルプロセスが呼び出されますが、これは希望どおりではない可能性があります。

また、呼び出しプロセスは、シェルによって実行された実際のプロセスが停止したときではなく、そのようなシェルが停止したときにのみ通知されます。

1
alk

system()はコマンドを入力し、ユーザーが入力したように実行します。私は主にsystem("pause"); system("cls");のように見ました

ただし、子プロセスを制御する必要がある場合は、フォークする必要があります。

0
Shark