#include<stdio.h>
#include <unistd.h>
main(){
int i;
printf("\t(%s)プロセスID.....%d\n","元",getpid());
printf("\t(%s)親プロセスID...%d\n","元",getppid());
if((i=fork())==0)
{ //子プロセスで実行する部分
printf("\t子プロセスでのfork()の値 : %d\n",i);
printf("\t(%s)プロセスID.............%d\n","子",getpid());
printf("\t(%s)親プロセスID...........%d\n","子",getppid());
printf("子プロセスを終了します\n");
}
else{//親プロセスで実行する部分
printf("\t親プロセスでのfork()の値 : %d\n",i);
printf("\t(%s)プロセスID.............%d\n","親",getpid());
printf("\t(%s)親プロセスID...........%d\n","親",getppid());
printf("親プロセスを終了します\n");
}
}
fork関数の振る舞いについてです。
上記のプログラムをgccでコンパイルして実行した場合出力結果が
/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
(元)プロセスID.....375
(元)親プロセスID...246
親プロセスでのfork()の値 : 376
子プロセスでのfork()の値 : 0
(子)プロセスID.............376
(子)親プロセスID...........375
子プロセスを終了します
(親)プロセスID.............375
(親)親プロセスID...........246
親プロセスを終了します
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
という感じで出力されました。
fork関数がプロセスの複製を行っていることと、戻り値が0と376の2つであることはわかりました。
また子プロセスには0を親プロセスには376を返すこともわかりました。
感覚的にはif文の真である子プロセス側の記述文と偽である親プロセス側
の記述文が同時に実行されているのではないかと考えましたが
同時に実行されているのに
printf("\t子プロセスでのfork()の値 : %d\n",i);
printf("\t親プロセスでのfork()の値 : %d\n",i);
で表示される値が違うのはなぜでしょうか。
i=fork()によって代入されているのはわかるのですが、
同時に実行されつつ何故2つの違う値をiは出力できるのかがわかりません。
また出力結果が
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
(元)プロセスID.....377
(元)親プロセスID...246
親プロセスでのfork()の値 : 378
(親)プロセスID.............377
(親)親プロセスID...........246
親プロセスを終了します
子プロセスでのfork()の値 : 0
(子)プロセスID.............378
(子)親プロセスID...........1
子プロセスを終了します
_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
子プロセスから見たときの親プロセスが1となっているのは何故でしょうか?
本来ならば377ではないでしょうか?
わかりにくい説明ですいません。
よろしくお願いします。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
あ~, 読み返してみたら用語が混乱してる (ついでに fork をミススペルしてる).... すみません, 言い直します.
基本的に, 全てのプロセスは「そのプロセス専用のデータ領域」を持ちます. そして, fork というシステムコールは「プログラムコードを共有する新たなプロセス」を作るのですが, そのときに, 親プロセスの持っている全てのデータを新たなプロセス用のデータ領域にコピーしてします. だから, fork から返った時点で「プログラムコードは共有するけどデータは個別」の 2個のプロセスになっています.
そして, fork は「親プロセス」には子プロセスの PID を, 「子プロセス」には 0 を返します. その返り値を「各プロセスが個別に持っている」変数 i に代入しているので, 親プロセスと子プロセスで違う値となっています.
No.1
- 回答日時:
fork をしたら, 論理的には別のプログラムだと思ってください.
別のプログラムだったら, 同じ変数に違う値が入っていても問題ないですよね.
で後者の方ですが, 親プロセス (folk したプロセス) が子プロセス (folk でできたプロセス) より先に終了するとそのようなことになります. Unix では, 親に先に死なれたみなしごプロセスは init (というプロセス) にひきとられます. init の PID は 1 ですから, そういう結果になっているんじゃないでしょうか.
ありがとうございます。
親プロセスが1になる理由はわかったのですが、論理的には別のプログラムという考え方が、うまく理解できませんでした。
もしよろしければ、さらにアドバイスをお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 環境学・エコロジー 二酸化炭素の排出 1 2023/08/07 16:40
- その他(学校・勉強) この中で間違ってある説明はありますか?詳しい方に教えていただきたいです。 A. 1つのプログラムが複 2 2023/07/14 01:15
- Windows 10 バッチファイルでのエクスプローラー終了 1 2022/05/30 14:32
- 哲学 真実の信仰=真理の探究 1 2022/11/26 09:03
- その他(コンピューター・テクノロジー) Texについてです。 jpgファイルを貼り付けても表示されないのですが、どうしたら表示できますか? 1 2022/06/30 23:42
- CPU・メモリ・マザーボード 今のCPUは2nmプロセスとか何やらで製造されているかと思いますが、このスケールをどんどん大きくして 3 2023/06/07 20:34
- 政治 私は文部科学省ヘ入り込んで投稿した私の建議文を彼らが私の依頼まましましょうか。? 2 2023/08/22 07:08
- その他(ソフトウェア) ソフトが異常終了します 1 2022/08/28 01:41
- 不安障害・適応障害・パニック障害 認知療法について 1 2022/09/14 20:20
- iCloud AppleID サポートからのメール 3 2023/07/05 15:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
タスクマネージャーのプロセス...
-
プロセスIDからウィンドウハ...
-
ShellExecuteExでハンドルの取得
-
別のプロセスの関数を呼び出す...
-
プロセスが実行中かどうか調べ...
-
Windowsでのfork方法
-
C#でのbatファイル実行結果取得
-
VC++6.0 「プロセスへ...
-
ロードアベレージが高いのです...
-
プロセスのアタッチ・デタッチ...
-
AppActivate関数について
-
非表示になったエクセルは?
-
他のEXEが起動しているかの確認
-
c言語でプロセスIDを調べたい
-
別プロセスをの実行パスを取得...
-
CreateObjectで作成したExcelの...
-
子プロセスのデバッグ方法について
-
警告『 別のプロセスで使用され...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
タスクマネージャーのプロセス...
-
C#でのbatファイル実行結果取得
-
プロセスのアタッチ・デタッチ...
-
VB6.0 SHELLで起動...
-
プロセスIDからウィンドウハ...
-
Process.Startの戻り値を後で取得
-
ウィンドウのタイトルからプロ...
-
他のEXEが起動しているかの確認
-
ADOでアクセスのレコードに...
-
怪しいプロセス教えてください。
-
別のプロセスの関数を呼び出す...
-
C++のプログラムをバックグラウ...
-
Linuxでのスレッド間メッセージ...
-
C++でシェルを起動
-
プロセスIDの取得方法について
-
OSPFでプロセスを分ける意義に...
-
非表示になったエクセルは?
-
Windowsでのfork方法
おすすめ情報