我有一个类,ServerManager
,它使用pexpect
监视并与另一个进程交互。不幸的是,没有一种更干净的方法来做到这一点。所讨论的进程不提供API。在
ServerManager
需要监视进程的输出,并在识别特定模式时触发事件。因为有多个这样的模式要监视,并且pexpect
的spawn.expect()
阻塞了当前线程,所以这些“侦听器”被分离成单独的线程,当它们与它们的模式匹配时,这些线程与主线程交互。在
其中一个例子是等待用户连接/断开连接:
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
中的线程安全问题吗?考虑到我与进程交互的唯一方法是监视其命令行输出,有没有更好的方法来监视这类事件?在
这里有两个线程对同一个文件描述符进行阻塞调用。我将实现这是一个单线程异步事件循环。
expect
方法应该能够监视是否有多个字符串可以为一个调用中的每个结果调用回调函数。我不确定pexpect是否真的能做到这一点(我不使用它),但是仔细看看它的文档。在相关问题 更多 >
编程相关推荐