11

このように使用しているプログラムは2つあります。

$ c_program | python_program.py

c_programはを使用して何かを出力しprintf()、python_program.pyはを使用して読み取りますsys.stdin.readline()

python_program.pyが印刷時にc_programの出力をすぐに処理して、それ自体の現在の出力を印刷できるようにしたいと思います。残念ながら、python_program.pyは、c_programが終了した後にのみ入力を取得します。

どうすればこれを解決できますか?

4

6 に答える 6

18

次のように、Cプログラムの最初(出力を実行する前)にstdoutをラインバッファリングするように設定するだけです。

#include <stdio.h>
setvbuf(stdout, NULL, _IOLBF, 0);

また

#include <stdio.h>
setlinebuf(stdout);

どちらもLinuxで動作しますがsetvbuf、C標準の一部であるため、より多くのシステムで動作します。

デフォルトでは、stdoutはパイプまたはファイル用にブロックバッファリングされるか、ターミナル用にラインバッファリングされます。この場合、stdoutはパイプであるため、デフォルトはブロックバッファリングされます。ブロックバッファリングされている場合、バッファがいっぱいになるか、を呼び出すと、バッファがフラッシュされますfflush(stdout)。ラインバッファリングされている場合は、各ラインの後に自動的にフラッシュされます。

于 2009-09-11T03:27:43.447 に答える
9

必要なのは、Cプログラムがすべての行の後にfflush(stdout)を呼び出すことです。たとえば、GNU grepツールを使用すると、オプション'--line-buffered'を呼び出すことができます。これにより、この動作が発生します。fflushを参照してください。

于 2009-09-11T02:43:34.973 に答える
7

Cプログラムを変更できる場合は、すでに回答を受け取っていますが、コードを変更できない/変更しないソリューションを含めると思います。

expectには、トリックを実行するunbufferというサンプルスクリプトがあります。

于 2009-09-11T04:51:18.913 に答える
2

flushcppプログラムでstdoutストリームを試してみることをお勧めします。

于 2009-09-11T02:40:18.177 に答える
1

すべてのUnixシェル(私が知っている)は、pty以外のものを介してシェルパイプラインを実装します(通常、それらはUnixパイプを使用します!-); したがって、のC / C ++ランタイムライブラリは、cpp_programその出力が端末ではないことを認識し、したがって、出力を(一度に数KBのチャンクで)バッファリングします。pytを介してパイプラインを実装する独自のシェル(またはsemiquasimaybeshelloid)を作成しない限り、パイプライン表記を使用して必要なことを行う方法はないと思います。

問題の「shelloid」は、標準ライブラリのモジュールまたはpexpectptyなどのそれに基づく高レベルの抽象化を使用して、Python(またはC、Tcl、または...)で記述されている可能性があります。 「ptyベースのパイプライン」を介して接続される2つのプログラムはC++で記述されており、Pythonはまったく関係ありません。重要なアイデアは、パイプの左側にあるプログラムをだまして、そのstdoutがターミナルであると信じ込ませ(そのため、ptyがトリックのルートにある必要があります)、ランタイムライブラリをだまして出力をバッファリングしないようにすることです。このようなシェロイドを作成したら、次のような構文で呼び出します。

$ shelloid'cpp_program | python_program.py '

もちろん、サブプロセスとしてスポーンし、stdoutがターミナルであると信じ込ませるpython_program必要があるという知識を書き込んで、 「ポイントソリューション」を提供する方が簡単です(つまり、たとえば、直接使用します)。ただし、システムが提供するCランタイムライブラリによって実行される通常のバッファリングを無効にしたい場合や、既存のフィルタなどを再利用したい場合など、実際には書き込みが望ましい場合があります。cpp_programpython_programpexpectshelloid

于 2009-09-11T02:35:11.980 に答える
-1

わかりました、これはばかげているように聞こえるかもしれませんが、うまくいくかもしれません:

pgmをファイルに出力します

$ c_program >> ./out.log

tailコマンドから読み取るPythonプログラムを開発する

import os

tailoutput = os.popen("tail -n 0 -f ./out.log")

try:
    while 1:
        line = tailoutput.readline()
        if len(line) == 0:
            break

        #do the rest of your things here
        print line

except KeyboardInterrupt:
        print "Quitting \n"
于 2009-09-11T02:58:54.543 に答える