0

我们有一个基于 asyncore 的网络客户端,用户的网络连接体现在一个Dispatcher. 目标是让从交互式终端工作的用户能够输入网络请求命令,这些命令将发送到服务器并最终返回答案。客户端被编写为异步的,因此用户可以同时在不同的服务器上启动多个请求,并在结果可用时收集它们。

当我们在一个选择循环中进行时,我们如何允许用户输入命令?如果我们点击select()只注册为可读的调用,那么我们将坐在那里直到我们读取数据或超时。在此(可能很长)时间内,用户输入将被忽略。如果我们总是注册为可写的,我们会得到一个热循环。

一种不好的解决方案如下。我们在自己的线程中运行选择循环,并通过调用我们在 Dispatcher 上定义的方法让用户将输入注入到线程安全的写入队列中。就像是

def myConnection.enqueue(self, someData):
    self.lock.acquire()
    self.queue.put(someData)
    self.lock.release()

然后,我们仅在队列不是 emtpy 时才注册为可写

def writable(self):
    return not self.queue.is_empty()

然后,我们将指定一个超时,因为select()它在人类尺度上很短,但对计算机来说很长。这样,如果我们在select用户输入新数据时只注册用于读取的调用,循环最终将再次运行并发现有新数据要写入。这是一个糟糕的解决方案,因为我们可能也希望将此代码用于服务器的客户端连接,在这种情况下,我们不希望您等待的死区select()时间超时。再次,我意识到这是一个糟糕的解决方案。

似乎正确的解决方案是通过文件描述符引入用户输入,以便我们可以在select仅注册为可读的调用中检测新输入。有没有办法做到这一点?

注意:这是为了简化此处发布的问题

4

1 回答 1

0

标准输入是可选的。将标准输入放入您的调度程序。

此外,我推荐Twisted用于任何事件驱动软件的未来开发。它比 asyncore 功能更丰富、文档更好、社区更大、性能更好等等。

于 2013-05-31T19:54:31.473 回答