2011-04-23 96 views
1

我有很多設備需要獲取狀態更新。一個套接字對象就是我所有的,而socket.recv()就是我需要的狀態。放入一個單線程應用程序,不會出現問題:如何在Python中實現線程socket.recv()?

class Device: 
    def receive(self): 
     log.debug("receive waiting: %r", self.device_id) 
     try: 
      packet = self.socket.recv(255) 
     except Exception as e: 
      self.report_socket_error(e) 
      self.reconnect() 
     log.debug("received response: %r", self.device_id) 
d = Device() 
d.connect() 
while True: 
    d.receive() 

然而,包裹在一個threading.Thread類相同的代碼會導致死鎖和滑稽的行爲。用鎖包裝並沒有改變任何東西。我將問題追溯到socket.recv()調用...那麼,如何實現多個線程,其中每個線程擁有一個套接字(1個線程只擁有一個套接字),它們能夠同時等待數據?

在此先感謝

+0

你爲什麼要鎖?你是否分享任何資源?根據POSIX發送/ recv是原子操作。可能是你沒有很好地使用線程。你能分享你已經實現線程的代碼嗎? – Arunmu 2011-04-23 14:14:46

回答

0

我知道這並不能回答你關於如何解決您的死鎖問題的問題,但是它將顯示爲線程的使用是開銷,你的情況:

你可以只使用一個線程在其中使用select()找出哪個套接字有可用的數據,然後處理報告的數據。除非處理時間長或您的協議更復雜select應該很好,並避免所有線程問題。

查看http://docs.python.org/howto/sockets.html#non-blocking-sockets瞭解更多詳情。

0

您必須讀取多少個不同的套接字?

  • 如果答案是「只有一個」,那麼只用一個線程。正如你發現的那樣,添加另一個不會幫助你,也只會使你的生活複雜化。
  • 如果答案是「幾個」,比組織這個方法確實每個套接字都有一個線程。 recv是一個阻塞操作,它使線程成爲組織代碼的有吸引力的選項。每個線程擁有一個單獨的套接字並在閒暇時讀取它。你應該沒有問題和僵局。

    只要沒有共享資源,就不需要鎖。即使您共享資源(日誌記錄,某些數據存儲等),也不要只使用簡單的鎖 - Python具有更高級的實用程序,例如Queue模塊。