2015-10-20 16 views
6

これらのことを実行する方法の例はたくさんあります。LinuxでのPythonでのプログラム間通信

1)異なるプログラム間で通信を行います。 pythonから文字列を送信するための標準的な方法です何

  • 2)この質問はどこにでも私が見てきた何の良い例を持っていない、

    しかし、ネットワークを介したクライアント/サーバー間の通信プログラムAをプログラムBにブロックし、この文字列をブロックして処理し、ループ内で別のものを待つ

答えに何度も近づいたような気がしますが、実際の例を作成することはできませんでした。

追加暗黙の要件:

  • 実は2つの切り抜いたプログラム:例は、実際には2つの切り抜いたプログラムを持っている必要があります(別途二つの画面にコマンドラインから実行することができる、すなわち二つのファイルprogA.py、progB.py同じマシン上で)、クライアントやサーバーを作成するために、何らかのフォークやマルチプロセスを使用しないでください。
  • データサイズの正確なバイト数を正確に取得する代わりに、可変長区切り文字列を合理的な長さまで送信できるようにする方法を提案してください。 (後者は、実装上、エラーが発生しやすくなります)。
  • 理想的には例えば、ローカルホストのインターネット接続に

を利用せずにこれを行います。

pipein = open(pipe_name, 'r') 
while program.KeepRunning: 
    action = pipein.readline()[:-1] 
    program.processLine(line) 
    time.sleep(1) 

をし、作家が使用しています:読者が使用している場合

command = "enable" 
pipeout = os.open(pipe_name, os.O_WRONLY) 
os.write(pipeout, command) 
os.write(pipeout, "\n") 

リーダーは空の文字列を読み取る無限ループで立ち往生http://www.python-course.eu/pipes.php で提案されます。興味深いことに、は、のコードの一部が実行されてから、空行を永遠に読み取る前に実行されています。if(action == 'enable'): longFunction()program.processLine関数に追加すると、興味深いことです。

一方、最近の低レベルの低レベルのsubprocessモジュールを使用するすべての例では、複数のアプリケーションではなくマルチスレッドアプリケーションのみが使用されます。他の実装には、ソケットとネットワーキングが含まれます。

私はソケットを利用しようとしましたが、これは、何かが間違ったタイプのエラーとなる可能性があります。多くの場合、Error 111: “connection refused”が表示されます。特定のコマンドを受け取ったときに実行されるPythonコードの一部がネットワーク設定を実際に変更します(たとえば、iptciptablesなどのコマンドをさまざまな引数で呼び出します)。localhostへのネットワーク接続を使用すると、デバッグし、一般的に厄介な問題に。 2番目のプログラムが同じマシン上で実行されるために不必要な部分のほかに、どのようなプログラム間通信でもネットワークインタフェースを使用する必要はありません。

+0

あなたは[multiprocessing.Queue](https://pymotw.com/2/multiprocessing/communication.html) – Pynchia

答えて

2

これは動作を意図したものです。同様の問題とFIFO動作の概要については、this answerを参照してください。あなたの質問に関連する部分は次のとおりです。

EOFを返すread()から(...)読者はそのことについて通知され、それ以上の作家がないとき。空の文字列は、ファイルの終わりに達した

f.readline()かのリターンを、空白行がある一方で:

file.readline()docsEOFに達したことを、''(空の文字列)を意味していることを言います'\n'で表され、1つの改行のみを含む文字列です。

これだけです。読んでみるたびに無限ループで空の文字列が得られます。これは、接続されているライターがなくなったと言います。

名前付きパイプを使用してタスクを解決することはできません。最も単純な方法は、作家がいないときに、しばらくの間眠ることです。ここでの実施例である:

# server.py 

import os 
import time 

pipe_name = 'pipe_test' 

if not os.path.exists(pipe_name): 
    os.mkfifo(pipe_name) 

with open(pipe_name, 'r') as pipe: 
    print("Listening for actions...") 
    while True: 
     action = pipe.readline()[:-1] 
     if action == '': 
      print("No clients. Sleeping...") 
      time.sleep(1) 
     else: 
      print("Action received:", repr(action)) 
# client.py 

import os 

pipe_name = 'pipe_test' 

if not os.path.exists(pipe_name): 
    os.mkfifo(pipe_name) 

print("Waiting for server to start...") 
with open(pipe_name, 'w') as pipe: 
    action = input("Enter action to send: ") 
    pipe.write(action + '\n') 

  • 低レベルの関数であるos.open()を使用してもポイントは、存在しません。 open()を使用すると、名前付きパイプと対話できます。
  • 最初のライターが接続されるまで、blocksを読み取るための名前付きパイプを開きます。したがって、最初のクライアントがパイプに接続されるまで、出力にListening for actions...が表示されません。同じことが、読者がいなくても始まった作家と同じです。
  • 「この文字列をブロックして処理してから、ループ内で別の文字列を待つ」という質問をしました。別のスレッドで文字列を処理しているのでなければ、現在の文字列が処理されるまで次の文字列を読み込もうとしません。
+0

を試してみましたか?一つのこと: '[:-1]はなぜ使われますか?私が正しく理解している場合、サーバがスリープしている間に複数のラインがクライアントによってパイプに追加された場合、それらのラインの最後だけが読み取られます。 – aphid

+0

'f.readline()'は '\ n'の後ろに行を返しますので、' \ n'を文字列の最後から削除するために '[:-1]'が使われます。いいえ、スリープ中に追加されたすべての行は、プロセスが起動すると処理されます。スリープ時間を増やし、スリープ時間中に複数の回線を送信することでテストできます。 Pipeは、サーバがスリープしている間にすべての行を保存します。 –