我想從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