• 締切済み

プロセスの生成(fork)

私はLinuxを始めたばかりのタコです。 参考書で少しずつ勉強しているのですが 「プロセスの生成にはforkを使用する」と記載されており プログラム例も載ってはいるのですが親プロセスと子プロセス一個の ケースしか記載されていません。 例にはPIDが0か0以外で親子を判断して別処理をさせると書いてありました。 例えば親プロセスと子プロセス2個以上を生成するにはどうしたらいいのでしょう?超ビギナーな質問で申し訳ありませんがタコを育てると思って どうか御教え下さい。宜しく御願いします。

みんなの回答

  • haporun
  • ベストアンサー率40% (230/562)
回答No.3

下記のお答え。 んんんと、それだと最後に作成されたプロセスで、forkの戻り値が0なので、ifを通らないままforを抜けて、何もしないプロセスになってしまうような・・・。 for(n = 0; n < 2; n++){ if(pid[n] = fork) break; } switch(n){ case文で0~3 (←3までであることに注意) } とすると、forループを抜けた時点で、 (1) nに0が入っている、親プロセス (2) nに1が入っている、(1)プロセスに作られた子プロセス (3) nに2が入っている、(2)プロセスに作られた子プロセス (4) nに3が入っている、(3)プロセスに作られた子プロセス ができます。 どういう経緯をたどるかというと、 (1) 親プロセスはn=0をセットし、forkの戻り値にIDが入るのでブレーク、forを抜けたあとのnは0。 (2) n=0のループでforkを呼び出した時点でプロセスが複製され、forkの戻り値が0なので、ブレークせずにnがインクリメントされn=1に。そしてforkを呼び出し、プロセスIDが返り、真なのでブレーク、forを抜けたあとのnが1。 (3) n=1のループでforkを呼び出した時点でプロセスが複製され、forkの戻り値が0なので、ブレークせずにnがインクリメントされn=2に。そしてforkを呼び出し、プロセスIDが返り、真なのでブレーク、forを抜けたあとのnが2。 (4) n=2のループでforkを呼び出した時点でプロセスが複製され、forkの戻り値が0なので、ブレークせずにnがインクリメントされn=3に。そしてn>2なのでループを抜け、forを抜けたあとのnが3。 というわけでforを抜けたあとswitchで判別するといいと思います。 これは自分でやったことであり、参考書とかを見たわけではないので、これが一番正しいとは言えないのですが、動作はしました、perl上ですが(笑)。 でもどの言語でも同じだと思います。 ちなみにperlではpid[n]には、あとのプロセスのIDは格納されません。 たとえばn=0のプロセスではpid[1]は入っていませんでした。 どうやら、複製されたプロセスで、変数は共有されていないようです。 もちろん、この部文はほかの言語でどうなるかわかりませんが。 if(!(pid[n]) = fork()) break; とすると、いちばん最初のプロセス(n=0)だけのpid[n]にすべてのプロセスIDが格納されました。 プロセスを作成するのは最初のプロセスだけですから。 長くなりました。 参考になれば嬉しいです。

shizuoka7
質問者

お礼

大変参考になりました。詳しく教えて頂いてありがとうございました。

  • haporun
  • ベストアンサー率40% (230/562)
回答No.2

forkはこれを呼び出した時点で、そのプログラムのメモリ内容をすべてコピーしたプロセスの複製を作ります。 ただし、1つだけ違う個所があります。 それはforkの戻り値です。 間違えやすい例を。 fork(); fork(); 1個目のforkで2つのプロセスに別れ、その2つが2個目のforkを呼び出すので結果4つできてしまう。 for(n = 0; n < 2; n++){ if(fork()) break; } というふうにやると、子プロセスが2つできます。 ちなみに、Cの質問なのかシェルスクリプトの質問なのかわからなかったので、言語は適当です。 適当に解釈してください。

shizuoka7
質問者

お礼

分かり易い例を書いて頂いてありがとうございます。 下記の様につくればよいのでしょうか? pid_t pid[2]; for(n=0;n<2;n++){ if(pid[n] = fork()){ switch(n){ case 0: 処理A(system("他に作成したプログラム")等)    break; case 1: 処理B    break; default: break; } break; } }

shizuoka7
質問者

補足

分かり易い例を書いて頂いてありがとうございます。 下記の様につくればよいのでしょうか? pid_t pid[2]; for(n=0;n<2;n++){ if(pid[n] = fork()){ switch(n){ case 0: 処理A(system("他に作成したプログラム")等)       break; case 1: 処理B       break; default: break; } break; } }

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

必要な個数分、fork()を繰り返して呼び出せばよいと思うのですが、 それではいけませんか?

shizuoka7
質問者

お礼

回答ありがとうございます。 ちょっと試してみます。

関連するQ&A