2013-02-12 14 views
14

は、システム上でフォーク/ execのを好むために何らかの理由がある2つの一般的なUNIXでのCから外部実行可能ファイルを実行する方法、をsystem()またはfork()/ exec()に変更しますか?

system() 

コールと

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

があるように見えますそれらが機能的に等価である場合(親プロセスは、子プロセスが終了するのを待っており、子プロセスから複雑な情報は返されません)。

答えて

18

systemは、(a)直接fork/execよりも遅く、(b)異なるシステムでは異なる動作をする可能性があり、(c)それを渡すとセキュリティ上の危険が生じる可能性があるコマンドインタープリタを実行します信頼できないソースからの文字列。また、systemは、子プロセスが終了するのを待っていますが、親プロセスと並行して実行することもできます。より一般的には

は、低レベルのフォーク/ execのはあなたに追加の制御を提供します:2つの操作の間、あなたはchdirする場合があります前に、またはに、オープンパイプ、クローズファイルディスクリプタ、設定、共有メモリなどを

(別のシステムでは、私はWindowsとUnixの間にフォークがないので):私はRed Hat LinuxとUbuntuを話しています。前者はBashを使ってsystemに渡すものを実行し、後者は軽量のPOSIX互換シェルです。)

+0

私は相違点を尋ねました。彼は 'system()'はOSのAPIであり、 'fork/exec'はシステムレベルの呼び出しだと言いました。これは本当ですか?私の理解では、OSへのAPIは、システムコールとは対照的に、追加のチェックが含まれている可能性があるため、より安全です。 – Celeritas

+2

@Celeritasある意味では(システムコールはOS APIでもありますが)私の答えで議論したように、あなたの結論は間違っています。 'system'はチェックを追加しません。チェックされていない機能が追加されます。 –

0

システム()はコマンドを入力して、ユーザーが入力したように実行します。 私はほとんどそれのように見たsystem("pause"); system("cls");

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

+5

'system(" pause ");は病気です!プログラムがユーザーに何か入力するのを待たせるのが最も非効率的な方法です。 –

+0

@JohnZwinckそれは大学のために十分だった:)プログラムが終了しようとしているときに、コンソールが 'そこにとどまるようにするためには、通常そこにいた。 – Shark

+1

次回は、 'cin >> dummy;'(またはscanf())のようなものを試してみてください。そして、仕事は学校よりも高い基準を持っているとは思わないでください! –

1

system()経由で行くと、シェルプロセスが呼び出されますが、これはあなたの望むものではない可能性があります。

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

3

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

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

+0

これは他の人が作成したカスタムツールなので、コードをライブラリにリファクタリングするか、sysやexecで呼び出すか、ソースのチャンクを自分のバイナリにコピーする必要があります。これは、実装の保守性のスピードとの間では難しい選択です。 – Sparky

+1

完全性のために、もう1つの選択肢があります。このサードパーティツールを呼び出すためにPythonのような高水準言語を使用し、独自のコードの "main()"としても機能します。つまり、独自のロジックをライブラリや実行可能ファイルとして公開し、Cから砲撃するのではなく、いくつかの種類のスクリプトを使用して、考えを結びつけます。 –

+2

system()とpopen()は、実際には2つの新しいプロセスを作成します.1つはシェル用で、もう1つはシェル内で実行されるコマンド用です。 – pelya

関連する問題