2011-07-11 10 views
0

簡単な質問を関数を呼び出す、Pythonスクリプトを実行することは可能である:3は常に端子を介して、私もわからないよん

私は、Pythonスクリプト、サーバーに接続し、Iのいずれか切断されるまで接続したままのネットワークスクリプトを持っていますそれは常にデータを受信して​​いて、他の仕事をしている私を蹴る(通常はそうしてはならない)。

スクリプト内で機能を起動するために、スクリプトが実行されている間にすべてのことが可能であるかどうか不思議でしたか?スクリプトが実行されている間に、何らかのデータをサーバーに送信するような衝動があったら、それを入力してこれを処理する関数に送信できますか?

可能かどうかは、私が試してみたり、見たことがないので、あまり確かではありませんでした。それが助けになるならば、私はUbuntuのLinuxで端末からスクリプトを実行しています。

答えて

0

詳細を記入することなく、私は一般的なアイデアのみを提供することができます。一度に2つのことを(サーバーからダウンロードし、データが送信されるのを待つために)行うには、複数のスレッドまたはプロセスのいずれかを使用する必要があります。複数のスレッドのいくつかの例を含むチュートリアルがありますhere。複数のプロセスを使用する場合は、multiprocessingパッケージを使用しています。

いずれの解決方法でも、同様の設定が必要です。残念ながらスレッドという用語を使用しますが、複数のプロセスを代わりに使用した場合は、プロセスと簡単に置き換えることができます。おそらく、(少なくとも)2つのスレッドであるかもしれないデータを送受信するためのスレッドと、何かを送るのを待つ別のスレッドがあります。これはthe producer/consumer problemの簡略化した例です。コマンド/データを待つスレッドは、が送信するデータをが生成する単純な入力ループになりますが、データを送信するスレッドはを使用してサーバーに送信します。

+0

私は必要に応じてコードを共有することができますが、これはまさに私が必要としているものと思われます。基本的には、TCPConnection経由でサーバに接続し、着実にデータを送受信するボットです。私がしようとしていることは、すべてが実行されている間に、関数の1つを呼び出して、その関数にプログラムをインターラップすることなくデータを送信できることです。たとえば、ボットには、サーバからの送信に応答して送信するデータがハードコードされている場合がありますが、ゲームのチャットにメッセージなどのカスタムを送信できるようにしたい場合は、 – WeaponsTheyFear

+1

また、単一スレッドの非同期イベントループを使用して、これらの種類のIOバウンド多重化をより簡単に行うこともできます。 Twistedフレームワークのようなものを使うことができます。すでにこの組み込み関数をサポートしているかもしれません。 – Keith

0

サーバーの内容を別のスレッドに貼り付けて(threadingモジュールを調べて)、raw_input/inputを介してユーザーとのやり取りにメインスレッドを使用します。

1

このような問題を解決するための通常の「UNIX」は、ソケットと標準入力ファイル記述子の両方でpollまたはselectです。次にソケットの 'IN'イベントでネットワーク入力を処理し、stdinファイル記述子の 'IN'イベントで端末入力を処理します。

これはWindowsにとっては移植性がありませんが、これはUNIXライクなシステムで行うのが最も自然な方法です。また、スレッドに付随するすべての問題を解決することはできません(そうでなければ、Pythonでもポーリングが必要です。

1

geventを見てみましょう:

geventが libeventのイベントループの上に高レベルの同期APIを提供するために、 greenletを使用してライブラリをネットワーキングコルーチンベースのPythonです。

およびgevent.socket

1

Jacek Koniecznyの解決策は良いと簡単です。より柔軟なメッセージの受け渡しを希望する場合は、ZeroMQを検討してください。これにより、メインプログラムの周りにさまざまなメッセージングソリューションを簡単に作成できるようになります。シングルスレッドを使用して、あなたのメインプログラムは次のようになります:

#!/usr/bin/env python 

import zmq 
from time import sleep 

CTX = zmq.Context() 

incoming = CTX.socket(zmq.PULL) 
incoming.bind("tcp://127.0.0.1:3000") 

outgoing = CTX.socket(zmq.PUB) 
outgoing.bind("tcp://127.0.0.1:3001") 

# Poller for the incoming messages 
poller = zmq.Poller() 
poller.register(incoming, zmq.POLLIN) 

def main(): 
    while True: 
     # Do things on the network 
     print("[Did things on the network]") 
     # Send messages if you want 
     outgoing.send("Important message") 
     # Poll for incoming messages 
     socks = dict(poller.poll(zmq.NOBLOCK)) 
     if incoming in socks and socks[incoming] == zmq.POLLIN: 
      message = incoming.recv() 
      # Handle message 
      print("[Handled message '%s']" % message) 

     sleep(1) # Only for this dummy program 

if __name__ == "__main__": 
    main() 

あなたはその後、プッシュし、メインプログラムからのメッセージにサブスクライブ(ZeroMQバインディングを持つ任意の言語で)クライアントを記述します。例プッシャー:

#!/usr/bin/env python 

import zmq 

CTX = zmq.Context() 

pusher = CTX.socket(zmq.PUSH) 
pusher.connect("tcp://127.0.0.1:3000") 

def main(): 
    pusher.send("Message to main program") 

if __name__ == "__main__": 
    main() 

例の加入者は:

#!/usr/bin/env python 

import zmq 

CTX = zmq.Context() 

subscriber = CTX.socket(zmq.SUB) 
subscriber.connect("tcp://127.0.0.1:3001") 
subscriber.setsockopt(zmq.SUBSCRIBE, "") 

def main(): 
    while True: 
     msg = subscriber.recv() 
     print("[Received message] %s" % msg) 

if __name__ == "__main__": 
    main() 

それはあなたが一つにプッシャーと加入者のプログラムを結合したいだろうように聞こえます。 ZeroMQを使用する場合は、the excellent user guideをご覧ください。

もちろん、複数のスレッドまたはプロセスなしでZeroMQを使用することもできます(スレッド間で個々のZeroMQソケットを共有しないように注意してください)。

関連する問題