我想从Queue.Queue或TCP套接字中读取消息,以先到者为准。 如何在不使用2个线程的情况下实现? 平台是CPython的2.7.5在WindowsPython - 如何在同一时间在队列和套接字上等待
4
A
回答
1
做到在一个单独的线程,你将不得不使用非阻塞方法,并将它们合并到单个事件循环中。实际上,我使用select
代替非阻塞套接字的I/O在这里,因为它是,如果你需要从多个插槽读取稍微干净...
import socket
import select
import Queue
import time
TIMEOUT = 0.1 # 100ms
def process_queue_item(item):
print 'Got queue item: %r' % item
def process_socket_data(data):
print 'Got socket data: %r' % data
def main():
# Build queue
queue = Queue.Queue()
for i in range(10):
queue.put(i)
queue.put(None) # Using None to indicate no more data on queue
queue_active = True
# Build socket
sock = socket.socket()
sock.connect(('www.google.com', 80))
sock.send('GET/HTTP/1.0\r\n\r\n')
socket_active = True
# Main event loop
while 1:
# If there's nothing to read, bail out
if not (socket_active or queue_active):
break
# By default, sleep at the end of the loop
do_sleep = True
# Get data from socket without blocking if possible
if socket_active:
r, w, x = select.select([sock], [], [], TIMEOUT)
if r:
data = sock.recv(64)
if not data: # Hit EOF
socket_active = False
else:
do_sleep = False
process_socket_data(data)
# Get item from queue without blocking if possible
if queue_active:
try:
item = queue.get_nowait()
if item is None: # Hit end of queue
queue_active = False
else:
do_sleep = False
process_queue_item(item)
except Queue.Empty:
pass
# If we didn't get anything on this loop, sleep for a bit so we
# don't max out CPU time
if do_sleep:
time.sleep(TIMEOUT)
if __name__ == '__main__':
main()
输出看起来像......
Got socket data: 'HTTP/1.0 302 Found\r\nLocation: http://www.google.co.uk/\r\nCache-Co'
Got queue item: 0
Got socket data: 'ntrol: private\r\nContent-Type: text/html; charset=UTF-8\r\nSet-Cook'
Got queue item: 1
Got socket data: 'ie: PREF=ID=a192ab09b4c13176:FF=0:TM=1373055330:LM=1373055330:S='
Got queue item: 2
etc.
0
你可以做下面几行内容:
def check_for_message(queue,socket,sock_accept_size=512):
socket.setblocking(0)
while True:
try:
sock_msg=socket.recv(sock_accept_size)
except socket.error:
"""Do stuff if there is no message"""
sock_msg=None
try:
que_msg=queue.get()
except Queue.Empty:
"""Do stuff if there is no message"""
que_msg=None
yield (que_msg,sock_msg)
然后你就可以使用遍历它:
for que_message,sock_message in check_for_message(que_instance,socket_instance):
print que_message,sock_message
2
有一个很好的技巧来做到这一点here适用于您的问题。
import queue
import socket
import os
class PollableQueue(queue.Queue):
def __init__(self):
super().__init__()
# Create a pair of connected sockets
if os.name == 'posix':
self._putsocket, self._getsocket = socket.socketpair()
else:
# Compatibility on non-POSIX systems
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 0))
server.listen(1)
self._putsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._putsocket.connect(server.getsockname())
self._getsocket, _ = server.accept()
server.close()
def fileno(self):
return self._getsocket.fileno()
def put(self, item):
super().put(item)
self._putsocket.send(b'x')
def get(self):
self._getsocket.recv(1)
return super().get()
相关问题
- 1. 如何让Win32线程在工作队列和套接字上等待?
- 2. Python套接字等待
- 3. 如何分配连接套接字的最短时间等待
- 4. 如何在等待连接时关闭服务器套接字?
- 5. 等待,并在同一时间蟒蛇
- 6. 套接字等待连接超时
- 7. `pthread_mutex_lock`和`pthread_cond_wait`是否在同一个队列中等待?
- 8. 长时间等待后套接字连接失败
- 9. 如何在Jenkins中配置排队等待时间的作业?
- 10. 缓冲区已满时的Java nio套接字等待时间
- 11. 是否有可能在异步套接字上等待连接
- 12. 套接字会从队列延迟一段时间后
- 13. 如何在序列运行前等待一段时间?
- 14. 在等待队列上放置进程时发生中断
- 15. Python:如何在不同的网络上连接套接字
- 16. Python套接字选择正在挂起 - 在等待套接字数据时执行其他任务?
- 17. 如何设置一个pyzmq套接字队列超时
- 18. JMS QueueReceiver - 需要等待某个时间,即使消息在队列上可用
- 19. 谷歌如何计算等待时间和在铬中的接收时间?
- 20. 如何在页面加载中减少“等待时间”和“接收时间”
- 21. 计算等待时间和处理时间的(非抢先)FCFS队列
- 22. 如何在观察CancellationToken的同时等待等待对象?
- 23. C:在超时的阻塞套接字上等待n个字符
- 24. OOP套接字不等待接受()
- 25. 多处理和套接字。如何等待?
- 26. 有没有办法在win32上等待监听套接字?
- 27. 同时在一个套接字上recv()和send()是否安全?
- 28. 当同一分支的工作正在等待时,清理jenkins队列作业
- 29. 阻塞队列将等待元素出列多长时间?
- 30. 请求servlet在队列中等待
你不能...轻松。类似于'select(2)'的东西可以用于两个阻塞套接字,但不适用于“队列”。如果可以接受的话,可以得到最接近的就是在循环中使用非阻塞方法。 – Aya
这是个坏消息。任何建议如何解决这个问题? – GabiMe