我们有一个基于asyncore的网络客户端,用户的网络连接体现在Dispatcher
。其目标是让一个在交互终端上工作的用户能够输入网络请求命令,这些命令将发送到服务器并最终返回一个答案。客户机被编写为异步的,这样用户就可以一次在不同的服务器上启动多个请求,并在结果可用时收集它们。你知道吗
在执行select循环时,如何允许用户输入命令?如果我们点击只注册为可读的select()
调用,那么我们将坐在那里直到读取数据或超时。在此期间(可能非常长)用户输入将被忽略。如果我们总是注册为可写的,就会得到一个热循环。你知道吗
一个坏的解决方案如下。我们在自己的线程中运行select循环,并让用户通过调用我们在调度器上定义的方法将输入注入到线程安全的写队列中。像这样的
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
调用中检测新的输入。有办法吗?你知道吗
注意:这是为了简化问题posted here
标准输入是可选择的。把标准输入你的调度员。你知道吗
另外,我推荐Twisted用于任何事件驱动软件的未来开发。它比asyncore有更多的特性,有更好的文档,更大的社区,性能更好,等等
相关问题 更多 >
编程相关推荐