Pythonのパイプ(pipe)を使って親プロセスと子プロセス間で通信する方法
子プロセスを生成する最も簡単な方法はforkを利用することです。fork()はPython標準ライブラリのosモジュールに含まれており、追加のインストールなしですぐに使えます。
ここでは、pipe()を使ってこの課題を実現します。pipe()は、あるプロセスから別のプロセスへ情報を受け渡すための仕組みです。ただし、pipe()による通信は一方向のみであるため、双方向のやり取りを行いたい場合は、送信用と受信用のそれぞれに対応した2本のパイプを用意する必要があります。
アルゴリズム
ステップ1:読み書き用のファイルディスクリプタ r、w を取得する ステップ2:fork を使用して新しいプロセスを生成する ステップ3:プロセスIDが 0 の場合、その処理は子プロセス側として動作する ステップ4:それ以外の場合は親プロセス側として動作する
サンプルコード
import os
def parentchild(cwrites):
r, w = os.pipe()
pid = os.fork()
if pid:
os.close(w)
r = os.fdopen(r)
print ("Parent is reading")
str = r.read()
print( "Parent reads =", str)
else:
os.close(r)
w = os.fdopen (w, 'w')
print ("Child is writing")
w.write(cwrites)
print("Child writes = ",cwrites)
w.close()
# Driver code
cwrites = "Python Program"
parentchild(cwrites)
コードの解説
os.pipe()を呼び出すと、読み取り用(r)と書き込み用(w)の2つのファイルディスクリプタが返されます。続くos.fork()によってプロセスが複製され、以降の処理は親と子で分岐します。
親プロセス側では、変数pidに子プロセスのPID(0以外)が入るため、if文が真になります。ここでは不要な書き込み側(w)を閉じ、パイプの読み取り側から子プロセスが送った文字列を受信します。
子プロセス側では、pidが0になるためelseブロックが実行されます。不要な読み取り側(r)を閉じた後、書き込み側(w)を通じてメッセージ「Python Program」を親プロセスへ送信し、ストリームを閉じて終了します。
このように、パイプの片方の端を閉じておくことが重要です。これにより、読み取り側では相手がデータを閉じた時点で正しくEOF(ファイル終端)を検知できるようになります。
実行結果
Child is writing Child writes = Python Program Parent is reading Parent reads = Python Program
-
Pythonで親ポインタを使って二分木の最小共通祖先(LCA)を求める方法
二分木と、その中の2つの特定のノード x・y が与えられたとします。このとき、2つのノードの最小共通祖先(Lowest Common Ancestor:LCA)を二分木の中から見つける必要があります。二分木における最小共通祖先とは、ノード x と y の両方が子孫となる最も深いノードのことです。なお、あるノードは自分自身の子孫でもあるとみなされる点に注意してください。該当するノードを見つけ、結果として返します。今回扱うツリーのノード構造は以下のとおりです。TreeNode: data: <整数> left: <TreeNode へのポインタ> righ
-
Pythonで式木(式ツリー)を構築して評価するプログラムの実装方法
はじめに本記事では、式木(Expression Tree)の後順巡回(後置記法・逆ポーランド記法)の結果が与えられたとき、そこから式木を復元(構築)し、さらにその式を評価して計算結果を求めるプログラムをPythonで実装します。最終的には、構築した式木の根(ルート)と、木全体を評価した値を返します。問題例次のような後置記法のトークン列が入力として与えられたとします。[1, 2, -, 3, 4, +, *]この列から式木を構築して評価すると、中間記法では (1 - 2) * (3 + 4) に相当し、計算結果は -7 になります。アルゴリズムの流れまず、子の接続位置を表す定数を定義しておきます