質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2782閲覧

fork()関数の挙動 C言語

daisuki64

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/09/15 04:27

c

1#include <unistd.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include <err.h> 5 6static void child() 7{ 8 printf("I'm child! my pid is %d.\n", getpid()); 9 exit(EXIT_SUCCESS); 10} 11 12static void parent(pid_t pid_c) 13{ 14 printf("I'm parent! my pid is %d and the pid of my child is %d.\n", getpid(), pid_c); 15 exit(EXIT_SUCCESS); 16} 17 18int main(void) 19{ 20 pid_t ret; // pid_t,,,int 21 ret = fork(); 22 if (ret == -1) 23 err(EXIT_FAILURE, "fork() failed"); 24 if (ret == 0) { 25 // child process came here because fork() returns 0 for chiild process 26 child(); 27 } else { 28 // parent process came here because fork() returns the pid of newly created child process (> 1) 29 parent(ret); 30 } 31 // shouldn't reach here 32 err(EXIT_FAILURE, "shouldn't reach here"); 33} 34

このコードはfork関数の挙動を表したコードなのですが、
fork()を発行すると、if文のelseに行き、parent(ret);を実行すると思うのですが、そのあとif (ret == 0)に行き、child();を実行していると思うのですが、if文の中でelseの方が後ろにあるのになぜ、戻ってif (ret == 0)が実行されるのでしょうか?
初心者ですみません。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

まずはfork()というシステムコールがどういうものであるのかを理解する必要があると思います。

fork()を実行すると、プロセス自分自身ををコピーした新しいプロセスが作られた結果、2つの同じプロセスが存在する状態になります。
2つのプロセスはそれぞれfork()を実行した直後から実行が再開されます。2つのプロセスはコピーであり、ほぼ同じものですが、唯一fork()からの戻り値が違っており、戻り値を見て自プロセスが親プロセスなのか子プロセスなのかを判断しそれぞれの処理に分岐するようになります(またはそうなるようにコーディングしていきます)。

以上を踏まえて、提示されたソースコードのprintf()による出力は1つのプロセスによって行われたものではなく、fork()によって分岐した親プロセスと子プロセスがそれぞれ別々に出力しているものになります。
何回か繰り返し実行してるうちに出力順が逆になることも確認出来るかもしれません。

投稿2020/09/15 05:02

編集2020/09/15 05:46
hidezzz

総合スコア1248

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

if文のelseに行き、parent(ret);を実行すると思うのですが、そのあとif (ret == 0)に行き、child();を実行していると思うのですが

違います。

  • 親プロセス…fork()に成功すればPID(1以上)を得て、parent(ret);を実行する
  • 子プロセス…fork()の返り値はゼロで、child();に進む

1つのプロセス内で実行が戻るわけではありません。

投稿2020/09/15 04:31

編集2020/09/15 04:31
maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

daisuki64

2020/09/15 04:58

私の環境でこのコードを実行すると I'm parent! my pid is 44501 and the pid of my child is 44502. I'm child! my pid is 44502. と帰ってくるのですが、挙動としてはelseが実行された後にif (ret == 0)が実行されたように思えるのですが、、、どういうことなのでしょうか。。。
maisumakun

2020/09/15 05:00 編集

> 挙動としてはelseが実行された後にif (ret == 0)が実行されたように思えるのですが 「親プロセスで」elseが実行された後に「子プロセスで」if (ret == 0)が実行されています。forkをされた瞬間から、両者のコードはそれぞれ別に動き始めます。
daisuki64

2020/09/15 05:02

あーそういうことなんですね! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問