[解決済み】fork()、vfork()、exec()、clone()の違いについて)
質問
Googleでこの4つの違いを探したのですが、膨大な情報があるかと思いきや、本当に4つのコールをしっかり比較したものがありませんでした。
そこで、これらのシステムコールの違いが一目でわかるような基本的な情報をまとめようとしたところ、以下のような結果が得られました。この情報は正しいのか、何か重要なことを見逃していないか?
Fork
: fork 呼び出しは基本的に現在のプロセスの複製を作成し、ほぼすべての面で同一にします (実装によってはリソース制限など、すべてがコピーされるわけではありませんが、できるだけ近いコピーを作成することを目的としています)。
新しいプロセス(子)は異なるプロセスID(PID)を取得し、古いプロセス(親)のPIDをその親PID(PPID)として持ちます。2つのプロセスは全く同じコードを実行しているので、forkの戻りコードでどちらがそうなのかわかります。もちろん、これはすべてfork呼び出しがうまくいくことを前提としています。そうでない場合、子は作成されず、親はエラーコードを受け取ります。
Vfork
: vfork と fork の基本的な違いは、vfork() で新しいプロセスを作成すると、親プロセスが一時的に停止し、子プロセスが親のアドレス空間を借用する可能性があるということです。この奇妙な状態は、子プロセスが終了するか、execve()を呼び出すまで続き、その時点で親プロセスが終了します。
プロセスは継続されます。
つまり、vfork()の子プロセスは、親プロセスの変数を予期せず変更しないように注意する必要があるのです。特に、子プロセスは vfork() 呼び出しを含む関数から戻ってはいけませんし、 exit() を呼んでもいけません (終了する必要がある場合は、 _exit() を使うべきです; 実は、これは通常の fork() の子プロセスにも当てはまります)。
Exec :
execコールは、基本的に現在のプロセス全体を新しいプログラムに置き換えるための方法です。exec() は現在のプロセスを、関数が指す実行ファイルに置き換えます。exec()エラーが発生しない限り、制御が元のプログラムに戻ることはありません。
Clone :
クローンはフォークと同様に、新しいプロセスを作成します。fork とは異なり、これらの呼び出しによって、子プロセスは呼び出し元のプロセスと、メモリ空間、ファイル記述子のテーブル、シグナルハンドラのテーブルといった実行コンテキストの一部を共有することができます。
cloneで子プロセスを生成すると、関数アプリケーションfn(arg)が実行されます。(これは、元のフォーク呼び出しの時点から子プロセスで実行を続けるフォークとは異なる)。fn引数は子プロセスが実行開始時に呼び出す関数へのポインタである.arg引数はfn関数に渡される。
fn(arg)関数のアプリケーションが戻ると、子プロセスは終了する。fn が返す整数が子プロセスの終了コードである。子プロセスは、exit(2) を呼び出すか、致命的なシグナルを受け取った後に明示的に終了させることもできます。
情報取得フォーム :
- forkとexecの違い
- http://www.allinterview.com/showanswers/59616.html
- http://www.unixguide.net/unix/programming/1.1.2.shtml
- http://linux.about.com/library/cmd/blcmdl2_clone.htm
お時間を割いていただきありがとうございます ! :)
どのように解決するのですか?
-
vfork()
は時代遅れの最適化です。 良いメモリ管理の前に。fork()
は親メモリの完全なコピーを作成するため、かなりコストがかかります。fork()
が続き、その後にexec()
これは、現在のメモリーマップを破棄して新しいメモリーマップを作成するもので、無駄な出費であった。 現在ではfork()
はメモリをコピーするのではなく、単に"copy on write"と設定されているだけですから。fork()
+exec()
と同じように効率的です。vfork()
+exec()
. -
clone()
が使用するシステムコールです。fork()
両者の違いは、どのデータ構造(メモリ空間、プロセッサの状態、スタック、PID、オープンファイルなど)が共有されているかどうかだけです。
関連
-
[解決済み] シェルで 'exec ls' を実行すると何が起こるか、またその理由は?[クローズド]。
-
[解決済み] vimdiff の出力ファイルにおける +-- の意味は何ですか?それをオフにする方法は?
-
[解決済み] Tarエラーです。アーカイブ内の予期しないEOF
-
[解決済み] SIGRTMAXとSIGRTMINの使い方は?
-
[解決済み] 次のコマンドの -print0 の意味を教えてください。
-
[解決済み] bashの「#$」はどういう意味ですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] プロセスとスレッドの違いは何ですか?
-
[解決済み] eval、exec、compileの違いは何ですか?
-
[解決済み] git branch、fork、fetch、merge、rebase、cloneの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】スタックスマッシュを検出しました
-
[解決済み】WSL - GEDIT サーバーを開始することができません。接続できませんでした。接続が拒否されました[closed]。
-
[解決済み】git clone時に「'https'のリモートヘルパーが見つかりません。
-
[解決済み】PytorchがCUDAは利用できないと言う件
-
[解決済み] "grep -q" のポイントは?
-
[解決済み] sudo mv home/* *」というコマンドは何をするのですか?[クローズド]
-
[解決済み] Nautilusのようにコマンドラインからマウントする方法とは?[クローズド]です。
-
[解決済み] grepコマンドで特定の列にマッチングさせる
-
[解決済み] Solaris では lsof -i が相当します。
-
[解決済み】forkとexecの違いについて