0

ServerManagerを使用して別のプロセスを監視およびインターフェースするクラス、がありますpexpect。残念ながら、これを行うためのよりクリーンな方法はありません。問題のプロセスはAPIを提供していません。

プロセスのServerManager出力を監視し、特定のパターンを認識したときにイベントをトリガーする必要があります。監視するそのようなパターンは複数あり、は現在pexpectspawn.expect()スレッドをブロックするため、これらの「リスナー」は、パターンが一致するとメインスレッドと相互作用する個別のスレッドにスピンオフされます。

そのような例の1つは、ユーザーが接続/切断するのを待っています。

import pexpect
from threading import Thread,Lock

usersLock = Lock()

class ListenerThread(Thread):

  def __init__(self, target, name=None, args=[], kwargs={}):
    super(ListenerThread, self).__init__(name=name)
    self.target = lambda: target(*args, **kwargs)
    self.isStopped = False # add a way to safely halt this thread

  def stop(self):
    self.isStopped = True

  def run(self):
    while not self.isStopped: # run until told otherwise
      try:
        self.target()
      except pexpect.TIMEOUT:
        # we can't wait forever...
        continue
      except pexpect.EOF:
        self.isStopped = True

class ServerManager(object):

  def __init__(self):
    self.process = pexpect.spawn(...) # Spawn the process
    self.numberOfUsers = 0
    # start up the listeners
    self.listeners = []
    connectListener = ListenerThread(self.waitForConnect, name="Connect listener")
    connectListener.start()
    disconnectListener = ListenerThread(self.waitForDisconnect, name="Disconnect listener")
    disconnectListener.start()
    self.listeners += [connectListener,disconnectListener] # keep track of the threads

  def waitForConnect(self):
    self.process.expect(...) # watch for the line that is printed when a user connects
    usersLock.acquire()
    try:
      self.numberOfUsers += 1
    finally:
      usersLock.release()

  def waitForDisconnect(self):
    self.serverProcess.expect(...) # watch for the line that is printed when a user disconnects
    usersLock.acquire()
    try:
      self.numberOfUsers -= 1
    finally:
      usersLock.release()

問題は、「接続」イベントと「切断」イベントが非常に信頼性の低い方法でトリガーされることです。およびのインスタンスを作成し、ServerManager接続/切断を10回(各アクションの間に約10秒待機)、numberOfUsers接続/切断のたびに確認しました。複数の試行にわたって、せいぜい約1/8の時間しか更新されていませんでした。

これはスレッドセーフの問題pexpectですか?プロセスとのインターフェースの唯一の手段がコマンドライン出力を監視することであるとすると、これらの種類のイベントを監視するためのより良い方法はありますか?

4

1 に答える 1

1

ここには、同じファイル記述子に対してブロッキング呼び出しを行う2つのスレッドがあります。これはシングルスレッドの非同期イベントループであると実装します。メソッドは、expect複数の文字列が1回の呼び出しの結果ごとにコールバック関数を呼び出すことができるかどうかを監視できる必要があります。pexpectが実際にこれを実行できるかどうかはわかりませんが(私は使用していません)、ドキュメントをよく見てください。

于 2011-08-21T05:35:40.650 に答える