そのような初心者の質問を申し訳ありませんが、Unix(システムコール)に精通していません。forkコマンドを理解しようとしていますが、forkコマンドが子プロセスの場合はpid 0を返すか、子IDの場合はpidを返します。プロセスが一度に1つの子しか持てず、そのpidを返すことができるか、複数の子プロセスを持つことができるかを知りたいですか?(実際には、複数の子があるかどうか、pidを返す方法、およびどのpidを返すかは想像できませんか?)
3 に答える
forkは Unixコマンドではありませんが、 fork(2) Posix man ページに記載されているシステムコールです。Linux のマニュアル ページはfork(2) -linux- here です。
成功すると、fork
syscall は 2 回返します: (呼び出し元の) 親プロセスで 1 回 (pid
子プロセスの を与える)、新しく作成された子プロセスで 1 回 (0 を与える)。それ以外の場合、2 つのプロセスはクローンであり (一部の Linux 実装ではfork
、Linux 固有のclone(2) syscall の上に実装されています)、ほぼ同じ状態で同じプログラムを実行しています (実際には 2 つのほぼ同一のコピー)。2 つの (親と子) プロセスが同時に実行されています (カーネルによってスケジュールされたタスクとして、おそらく異なるプロセッサ コアで並行して実行されます)。
fork(2)
syscall は (めったに) 失敗することがあります (例: fork bombを回避するため) 。たとえば、setrlimit(2) syscallRLIMIT_NPROC
で設定された制限に達した場合などです。失敗した場合、syscall は -1 を返すので、チェックする必要があります。すべてのシステムコールの失敗をチェックすることは良い習慣であり、例外ではありません。fork
errno
fork
fork はプロセスを開始する通常の方法です。ユーザー プロセスはすべて [いくつかのまれな例外を除いて]システムコール (または 、またはfork
のようなバリアント) によって開始されます。特に、コマンド (や など) をシェル (たとえば、端末エミュレータで実行中) に入力すると、シェルは自分自身を -ing し、次に必要なプログラムを -ing することがよくあります (例外は のようなシェル組み込み)。vfork(2)
clone(2)
ls
date
/bin/bash
fork
execve
cd
Linux システム上のほぼすべてのプロセスが によって作成されていることに注意してくださいfork
。例外は、/sbin/init
または/sbin/modprobe
...のようなカーネル起動プロセスです。
何度も呼び出すことができますfork
(典型的なシェルの実装では、 のような組み込みのものを除いて、すべてのコマンドに対してそれを行います。またはcd
のようなフリー ソフトウェア シェルのソース コードを調べたいと思うかもしれません)。最終的には、 wait(2)またはsyscallを使用して子プロセスを待機する必要があります。プロセスは、 execve(2)システムコールを使用して、実行可能ファイルとアドレス空間を変更できます。そのアドレス空間は、 mmap(2)および関連するシステムコールを使用して変更できます。sash
bash
waitpid(2)
strace -f
たとえば、シェルによってどのようなシステムコールが行われたかを理解するために使用したい場合があります。
高度な Unix プログラミングの本と高度な Linux プログラミングの本を読むことを強くお勧めします (後者は、無料のライセンスでオンラインで入手できます)。
を呼び出すたびに、単一の子プロセスがfork()
作成され、その単一プロセスの PID のみが返されますが、fork()
複数回呼び出して複数の子プロセスを作成することを妨げるものは何もありません。
分岐した子プロセスが終了するまで、wait() または waitpid()を忘れないでください。そうしないと、ゾンビ プロセスがぶらぶらしている可能性があります。
ひねりを加えた他の人と同じ答え:各プロセスが1つの子しか作成できない場合(fork()を1回だけ使用)、それはプロセスの系統にとって何を意味しますか?これは、たとえば、ちょうど1行あることを意味しinit -> login -> shell -> ls
ます。そのようなシステムをご希望ですか?あなたの結論は何ですか?