2011-10-15 15 views
12

新しいプロセスを作成するのになぜUnixがfork()を持っているのか分かりません。 Win32 APIでは、CreateProcess()が新しいプロセスを作成し、そのアドレス空間に実行可能ファイルをロードし、エントリポイントから実行を開始します。しかし、Unixは新しいプロセスを作成するためのフォークを提供しています。別のプロセスを実行したいのであれば、なぜ私は自分のプロセスを複製するのでしょうか?なぜUnixはfork()を持っていますが、CreateProcess()は持っていませんか?

だから、私は、これら2つの質問をしてみましょう:

  1. fork()た場合、その後exec()たちは、ほぼすべてのケースでfork()exec()を呼び出しますので、なぜ機能forkexec(const char *newProc)はありません、より効率的でしょうか?
  2. もっと効率的でない場合、なぜfork()が存在しますか?

答えて

11

fork()呼び出しは十分である。これプロセスの作成にシステムコールを複雑にするのではなく、子プロセスでI/Oリダイレクトを調整するなどのことが可能になります。SUIDまたはSGIDプログラムでは、子プロセスは他のプロセスを実行する前に昇格された特権を失います。

複雑な方法でプロセスを作成する場合は、posix_spawn()関数を参照してください。

#include <spawn.h> 

int posix_spawn(pid_t *restrict pid, const char *restrict path, 
     const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

int posix_spawnp(pid_t *restrict pid, const char *restrict file, 
      const posix_spawn_file_actions_t *file_actions, 
     const posix_spawnattr_t *restrict attrp, 
     char *const argv[restrict], char *const envp[restrict]); 

違いはposix_spawnp()は、実行可能ファイルのPATH上で検索を行います。

posix_spawn_file_actions_tposix_spawnattr_tの型(参照されているマニュアルページの一番下にある '関連項目'のリンクに従ってください)に対応するための機能があります。

これは、Windows上ではCreateProcess()とかなり似ています。しかし、大部分の場合、の直後にexec()を使用する方が簡単です。


私はあなたが何を意味するか理解していません。子プロセスコードは私によって書かれるので、if (fork() == 0)と子供のmain()の冒頭にこのコードを書くことの違いは何ですか?

実行するコードは、あなたが書いたコードではないため、子プロセスの開始時に何が起こるのかを変更することはできません。シェルを考える。あなたが書いたものだけがシェルから実行されるプログラムであれば、人生は非常に貧困になるでしょう。

多くの場合、実行するコードは多くの異なる場所から呼び出されます。特に、パイプラインで実行されることがあり、時にはパイプなしで実行されるシェルとプログラムを考えてください。呼び出されるプログラムは、I/Oリダイレクションとフィックスアップを実行する必要があるかどうかを判断できません。呼び出し元のプログラムは知っています。

呼び出し元のプログラムが昇格特権(SUID特権またはSGID特権)で実行されている場合は、別のプログラムを実行する前にそれらをオフにしたいのが普通です。何をすべきかを知るために他のプログラムに依存しているのは...愚かなことです。

+0

私はあなたが何を意味するのか理解できませんでした。子プロセスコードが私によって書かれるので、if(fork()== 0)と子コードのmain()の先頭にこのコードを書くことの違いは何ですか? –

+0

hmmだから、fork() - exec()のようなことをやるほうが簡単だと言っています(私はリダイレクト、特権を取り戻すなど)。 –

+1

はい: 'posix_spawn()'に必要な曲げと比較して、 'exec()'を使う前に、 'fork()'を使い子どもに必要なアクションを実行させる方がずっと簡単です。 'posix_spawn()'の根拠を読んでください。それはかなり啓発されている(少なくとも、それは私にとって)。 'posix_spawn()'でできることのリストは印象的ですが、 'fork()'が提供するものよりも複雑です。 –

3

UNIXライクなオペレーティングシステムは、(少なくとも最近のLinuxやBSDカーネル)一般非常に効率的なfork実装を持っている - いくつかの言語で、それに基づいて「ねじ切り」の実装があることを「とても安い」です。

最後に、forkexec関数は〜nです - アプリケーションコードのn行のいくつかの小さな値。

私は確信してWindowsがこのような有用なForkProcessを持っていた:(

コーディング幸せにしたい。


A cnicutarがCopy-On-Write (COW)を使用したものな戦略である、言及した。

+2

しかし、私は非常に効率的なフォークの後に別のものに変換処理をする場合は、それは新しいを作成することをお勧めではありません最初からプロセス?私自身のプロセスを複製する必要はありません。これは私が得るものではありません –

+0

@Ali Veli Modernのフォークはプロセスを全く複製しません。 "write on write"を参照してください。 – cnicutar

+0

私は新しいプロセスを作成すると言うことができます。 c-o-wかどうか、フォークは何か正しいですか?だから私はちょうど新しいプロセスを作成する場合、私はこれを何もしないだろうと思う(たとえそれが1つの命令であっても)。 –