• 締切済み

python: fork後の標準出力について

言語はpythonです。(バージョン : 2.6.6) 以下の二つの単純なpythonスクリプト   test.py, exe_fork.py があります。 [test.py] #!/usr/bin/env python import subprocess proc = subprocess.Popen("./exe_fork.py", stdout=subprocess.PIPE) result = proc.stdout.read() print result [exe_fork.py] #!/usr/bin/env python import os import time pid = os.fork() if pid != 0: print "parent\n" else: time.sleep(5) print "child\n" [動作] 各スクリプトの動作としては、 test.pyがexe_fork.pyをPopen(stdoutはPIPEで受信)で実行し、 read()メソッドでexe_fork.pyの標準出力を受け取り、表示する。 exe_fork.pyはforkして、   親プロセスは"parent"と出力   子プロセスは5秒後に"child"と出力 です。 [実行結果] test.pyを実行すると 5秒後に   parent   child と表示されました。 これを実行する前は実行後すぐに "parent" と表示されてスクリプト終了するのだと予想しておりました。 しかし実際はexe_fork.pyの親と子の両方のプロセス終了するまで何も表示されず 両プロセスが終了した後にtest.pyのread()メソッドが完了するようです。 (どういうしくみでそうなっているのかよくわかりません。。) [質問・相談] test.pyでexe_fork.pyの親プロセスの標準出力だけを反映する方法ございませんでしょうか? なお、都合上、以下の条件を満たしている必要がございます。  条件1: test.py側のソースは変更しない  条件2: exe_fork.pyの親プロセスが終了した時点でtest.pyのread()メソッドが終了する  条件3: forkptyは使わない [参考]  exe_fork.py側で子プロセスのみsys.stdout.close()してみましたが結局exe_fork.pyの子プロセスが終了するまで(=5秒経過するまで)test.pyのread()メソッドは完了しませんでした。   よろしくお願いします。

みんなの回答

回答No.1

sys.stdout.flush() は試してみましたか?

hi_ro_yu_ki
質問者

お礼

早速ありがとうございます。 ご提示いただいたように、sys.stdout.flush()を exe_fork.pyの time.sleep(5) の直前でを実行しましてみましたが現象は変わりませんでした。 ↑の認識合ってますか? もし何か試せるようなことがあればまたお願いします。

関連するQ&A

  • pipeの使い回し

    パイプをつかってpythonやirbなどのラッパーをつくりたいのです。入出力、2本のパイプをつくって、fork()してchildはstdout, inをつなげてexec。parentはパイプから受け取った出力を画面に。画面入力をパイプにおくるように作ろうとしています。parent側でwrite(pipe, str, strlen(str))とするも、パイプをcloseしなければchildからのreadができなくて、引き続きパイプを使いたくてもいったんcloseしているのでもうこのパイプが使えなくなります。パイプを使った通信は一度きりできらなければならないのでしょうか?継続してつかい続ける手法をご存知の方っていらっしゃいませんか?

  • 別々に実行のpythonでグローバル変数できる?

    python初心者です。 例えばなんですが、 test1.py test2.py 2つのpythonコードを用意して、 test1.py側で1秒間ごとにインクリメントしていくループの処理を実行しながら、test2.pyではcronなどで定期実行させて、test1.pyでインクリメントさせている変数をprintしていくようなコードを作ることは可能でしょうか? 今回のような別々に実行させておいて、変数をtest1.py、test2.py間で変数を共有するようなグローバル変数というのはできますでしょうか? ご教示頂きますよう、どうぞよろしくお願い致します。

  • 標準出力/標準エラー出力を時系列にファイルへ

    画面への文字出力が、標準出力(stdout)と標準エラー出力(stderr)の 両方もつような、コンソールアプリ(exe形式)のツールを動作させたときに、 画面上には、 stdout1 STDERR1 stdout2 STDERR2 stdout3 STDERR3 のような順番で処理順にメッセージが出るのですが、 これをファイルに落とそうとして、  C:\>hoge.exe 1> log.txt 2>1& とすると、log.txtの中身が、 C:\>type log.txt STDERR1 STDERR2 STDERR3 stdout1 stdout2 stdout3 のような標準エラー出力が先に吐き出される順番になってしまっています。 これを、exe実行前に、MS-DOSとして何らかの設定を行うことで、 ファイルに落とした時も、出力された文字が時系列に保存されるように する方法はあるでしょうか? よろしくお願いします。

  • forkについて

    fork文を使った問題について質問です。 #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main() { pid_t pid1,pid2; if((pid1 = fork()) == 0) printf("I am a first child with pid = %d,My parent pid is %d.\n",getpid(),getppid()); else if(( pid2 = fork()) == 0) printf("I am a second child with pid = %d,My parent pid is %d.\n",getpid(),getppid()); else printf("I am a parent with pid = %d.\nMy first and second children are %d and %d.\n",getpid(),pid1,pid2); exit(EXIT_SUCCESS); } このようなプログラムが与えられました。 問題は 1.このプログラムを改造して、1つの親プロセスから100の子プロセスを順に生成するプログラムをつくるというものと 2.1つの親から子プロセスを生成し、その子プロセスの孫プロセスを生成するプログラムをつくれというものです。 1はfor文を使えばできそうなのですが、forkの基礎が出来ていないのでどうループを回せばよいか分かりません。 2もfork内でforkを実行すればできそうだと思ったのですがうまく動かず・・・。 どうか正しく動くようなプログラムを教えてください!お願いします。

  • Pythonのインストール方法

    これからPythonを始めようと思っている者(PCの知識も全然ありません)です。以下の4つのファイルをインストールしなくてはなりません。 (1)Python-2.3.5.exe (2)win32all-153-py2.3.exe (3)scipy-0.6.0.win32-py2.3.exe (4)numpy-1.0.4.win32-py2.3.exe (1)、(2)は無事インストールできました。しかし(3)、(4)を実行しようとすると、 option /arch not understood. only native, nosse, sse2 and sse3 are valid と表示されて、止まってしまいます。調べてみてもよく分かりません。どうしたらよいか教えてください。m(__)m ちなみに(3)、(4)はhttp://www.scipy.org/で入手しました。

  • Rubyから外部プログラムを実行し、その出力を..

    Rubyから外部プログラムを実行し、その出力を受け取り、加工したいのですがよくわかりません。 stdin, stdout, stderr = win32-open3.popen3("XXX.exe") とすれば何とかいけそうなんですが、win32-open3が今は使われていないようです。 他に代わるものがあるのでしょうか? ちなみに、Rubyのバージョンは1.8.7です。 よろしくお願いします。

    • ベストアンサー
    • Ruby
  • 標準出力と標準エラー出力を変数にセットしたいです。

    始めたばかりの初心者の為、変な質問でしたら申し訳ありません。 標準出力と標準出力を別々の変数にセットしたいのですが、そのやり方が分からず困っています。 やりたいことは、 コマンド(diffやcatなどの)実行結果の標準出力と標準エラー出力を それぞれ「任意の文字_受取パラメータの値」にセットすることをしたいです。 下記は、1回ファイルに出力して、それを読んで変数にセットするように記述したものです。 ※記述間違っていたらすみません。 ファイルに書かなくても、パイプやその他コマンドなどで出来る方法はないでしょうか? ex) test.sh 1.txt 2.txt TEST01 で実行 #!/bin/sh parm1 = $1 parm2 = $2 parm3 = $3 diff "${parm1}" "${parm2}" > test.log 2> err.log eval w_stdout_${parm3}=¥`cat test.log¥` eval w_stderr_${parm3}=¥`cat err.log¥` eval echo "stdout:¥"¥{w_stdout_${parm3}}¥"" eval echo "stderr:¥"¥{w_stderr_${parm3}}¥"" ※実行した結果 stdout:diff結果 stderr:空白 お手数ですが、何卒宜しくお願い致します。

  • fork()の挙動について質問させてください

    fork()の挙動がいまいち良く分からないので質問させてください。 自分はPHPでなのですが、fork()はCで使われるのが多いだろうということと、概念を知りたいとの事でこちらで質問させていただきました。 以下のように書きLinuxの端末にて実行しました。 目的は、 1. 2つの子プロセスを作り、それらを同時並行処理したい 2. 同時並行処理なので3秒後に処理を終わらせて出力したい という事です。 #!/usr/local/bin/php -q <?php $time = time(); $pid = pcntl_fork(); if ($pid == 0) { $j; for ($j=0; $j < 3; $j++) { printf("child1: %d\n", $j); sleep(1); } } else if($pid > 0) { pcntl_wait($status); print ("Parent-a\n"); } else { die('fork できません'); } $pid = pcntl_fork(); if ($pid == 0) { $i; for ($i=0; $i < 3; $i++) { printf("child2: %d\n", $i); sleep(1); } } else if($pid > 0) { pcntl_wait($status); print ("Parent-b\n"); } else { die('fork できません'); } echo "time:" . (time() - $time) . "sec\n"; すると、6秒後にまず child1: 0 child1: 1 child1: 2 child2: 0 child2: 1 child2: 2 time:6sec child1: 0 child1: 1 child1: 2 Parent-b time:6sec が出力され、その3秒後に Parent-a child2: 0 child2: 1 child2: 2 time:9sec Parent-a Parent-b time:9sec が出力されました。 分からない点は以下の通りです。 1. Parent-bがParent-aより前に表示されたり、 child1: 0 child1: 1 child1: 2 child2: 0 child2: 1 child2: 2 及びParent-a Parent-bを出力したいのに、 なんかそれ以外のものが色々と不思議な順序で出力されている上、 9秒も処理時間にかかり、並行処理ではなく逐次処理になっているように見える。 2. 確か"Unix/Linuxプログラミング理論と実践"だったと思うのですが、Unix系の本にて 子作成(親のコピー) -> 子処理中、親は居眠り -> 子exit() -> 親wait() -> 親起きる という感じで書かれていたように思いますが、 実行例のParent-a等を見ると、挙動が分かりません。 長くなり申し訳ございませんが、もし宜しければ間違っている点をご指摘していただけないでしょうか? また、上記に書いた"目的"を実現するためのCなどで宜しいですのでコード例など部分だけで宜しいですので挙げて頂けたら幸いです。 申し訳ございませんが、宜しくお願いいたします。

  • pythonのエラーについて教えて下さい。

    pythonの勉強をおこなっている超初心者です。 ネットでみた。以下のサンプルコードを実行しようとしました。 # -*- coding: utf-8 -*- print u'モジュールのロード' def test(): print u'関数:testを呼び出しました' if __name__ == '__main__': print 'python-izm' # print 'パイソンイズム' test() しかし、以下の様なエラーとなってしまいます。 File ”test02.py"、line 9 print ’python-izm'  ^ indentionError:expected an indented block ネット調べてみたとことpythonのインデントのエラーだとわかりました。 pythonはインデントで実行範囲を認識するので、 そこがうまく記述できていないであろうとは思うのですが、何回か試したのですが うまく動いてくれません。 どなたか御指南下さい。

  • python3でMITMf

    MItMfというツールをpython3で実行しようとしたらエラーが出ました。 File "/home/kali/MITMf/mitmf.py", line 38 print get_banner() ^ SyntaxError: invalid syntax そもそもpythonで実行しようとしたらサポート終了なので次の リリースで削除予定と出ていました。 ご教示お願いします。

専門家に質問してみよう