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

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

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

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

2回答

4386閲覧

プロセスの親子関係の親プロセスが正常終了するタイミング

sequelanonymous

総合スコア123

CPU

CPUは、コンピュータの中心となる処理装置(プロセッサ)で中央処理装置とも呼ばれています。プログラム演算や数値計算、その他の演算ユニットをコントロール。スマホやPCによって内蔵されているCPUは異なりますが、処理性能が早いほど良いとされています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

1グッド

1クリップ

投稿2019/02/05 14:55

編集2019/02/06 06:30

プロセスの仕組みについて勉強しています。
なぜ、以下のようなアウトプットになるのか理解できません。os.fork()の箇所で子プロセスが生成され、「親プロセス: 69314」が2つ出力されると思っていましたが、どうして以下のような結果になるのでしょうか?print(f'親プロセス: {os.getpid()}')の箇所で親プロセスは、正常終了し、子プロセスが残った状態でprint(f'子プロセス: {os.getpid()}')が出力されているのでしょうか?
しかし、printは、システム関数であるため、printの処理が終わったからといって正常終了したことにはならないと思っています。

python

1bash-3.2$ cat test.py 2import os 3 4if os.fork(): #os.fork()が実行されると0が返却され、子プロセスはelse内の処理に入りprint文を実行する 5 print(f'親プロセス: {os.getpid()}') 6else: 7 print(f'子プロセス: {os.getpid()}') 8bash-3.2$ python test.py 9親プロセス: 69314 10子プロセス: 69330 11bash-3.2$
YouheiSakurai👍を押しています

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

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

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

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

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

guest

回答2

0

誤解がある気がします。

python

1import os 2 3if os.fork(): 4 print(f'親プロセス: {os.getpid()}') 5else: 6 print(f'子プロセス: {os.getpid()}')

このコードでforkするのは「os.fork()が呼ばれた(厳密には呼ばれたあとに内部でforkの処理が終わった)とき」です。os.fork()が返ってifが実行される時点では親プロセスと子プロセスに別れ、それぞれで別の道を歩んでいます。

子を孤児としてinitに看取らせる場合はこう。親がさっさと死んだあと、initが引き取ってwaitします。

python

1import os 2import time 3 4if os.fork(): 5 print(f'親プロセス: {os.getpid()}') 6else: 7 time.sleep(3) 8 print(f'子プロセス: {os.getpid()}')

これの理解も違う。

python

1import os 2import time 3 4os.fork() 5print('親プロセスは死んだ') # 親プロセスはforkした瞬間に死ぬ 6 7for i in range(5): 8 time.sleep(1) 9 print(f'孤児として生きてる {i} : {os.getpid()}')

# 親プロセスはforkした瞬間に死ぬって、そんな訳無いでしょう。親と子でそれぞれ下のforが実行されます。だから10回出力されるんです。

python

1import os 2import time 3 4print("親のpid", os.getpid()) 5os.fork() 6 7for i in range(5): 8 time.sleep(1) 9 print(os.getpid()) 10 11""" => 12親のpid 21168 1321169 1421168 1521169 1621168 1721169 1821168 1921168 2021169 2121169 2221168 23"""

forkの何たるか、というところから勘違いしている可能性大なので、勉強し直しましょう。

投稿2019/02/05 15:43

hayataka2049

総合スコア30933

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

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

sequelanonymous

2019/02/06 06:27

ありがとうございます!参考になります。
guest

0

自己解決

elseで抜けると正常終了することになる。
例えば、以下の例だと、for文のため、親プロセスが正常終了せず、生きたままになっている。

python

1bash-3.2$ cat test2.py 2import os 3import time 4 5os.fork() 6print('親プロセスは死んだ') 7for i in range(5): 8 time.sleep(1) 9 print(f'孤児として生きてる {i} : {os.getpid()}')

出力結果

bash-3.2$ python test2.py 親プロセスは死んだ 親プロセスは死んだ 孤児として生きてる 0 : 69728 孤児として生きてる 0 : 69744 孤児として生きてる 1 : 69728 孤児として生きてる 1 : 69744 孤児として生きてる 2 : 69744 孤児として生きてる 2 : 69728 孤児として生きてる 3 : 69728 孤児として生きてる 3 : 69744 孤児として生きてる 4 : 69744 孤児として生きてる 4 : 69728

投稿2019/02/05 15:05

編集2019/02/06 06:26
sequelanonymous

総合スコア123

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

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

KSwordOfHaste

2019/02/06 00:20

「elseで抜けると終了」というのは表現としては曖昧に思えます。スクリプト上のコードが全て実行されそれ以上なにも実行することがなくなったら終了と表現した方がよいでしょう。 ご質問のコードでいえば親は(A)を実行した後、if文の次にある文の実行を継続しますがそれ以上なにも書かれないのでそこでプロセスが終了します。子プロセスも同様で(A)のかわりに(B)を実行しますが、それ以降は親と同じ運命をたどります。 if os.fork():  print(...) # (A) else:  print(...) # (B)
sequelanonymous

2019/02/06 06:47 編集

ありがとうございます!言い方を間違えました。os.fork()は、0をかえすので子プロセスはelse内でprint文を実行するという理解です。
hayataka2049

2019/02/06 16:52 編集

>os.fork()は、0をかえすので 子ではそうですが親側では子プロセスのpidが返りますよ。 >子プロセスでは 0 が返り、親プロセスでは子プロセスの id が返ります。 https://docs.python.jp/3/library/os.html#os.fork 最初に起動されたときは当然(のちの)親プロセスしかいない訳ですが、forkはこの親プロセスをコピーして子を作るイメージです。親子の違いは主にpidとforkの返り値(細かいことを言い出すと他にもいろいろあると思いますが)。コピーされた後は、それぞれが別々に同じ位置から実行されます。 親側ではforkで子のpidが返っているので条件がTrueになり、子側では0が返っているのでFalse……という動作ですね。
sequelanonymous

2019/02/07 02:01

pidがかえるんですね。これで納得がいきます、腑に落ちました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問