簡體   English   中英

在Python 3可靠隊列基於線程間通訊

[英]Reliable queue based inter-thread messaging in Python 3

我正在嘗試使用queue.Queue()類在線程之間進行通信。 我從來沒有在2.x中遇到過問題,但是最近,在3.x中對我來說似乎確實不可靠。

我從隊列開始,作為模塊中的全局變量。 兩個線程都在此模塊中。

q = queue.Queue()

線程1具有put命令:

global q
q.put(“Hello”)

線程2有一個get命令:

global q
z = q.qsize()
q.get_nowait()

我在pycdev調試器中看到在put之后1不是不為空,但是get仍然返回空,並且get命令之前z為0。 這對我來說真的很奇怪。 我懷疑范圍不匹配,但無法弄清楚這可能在哪里發生。 有誰知道條件可能會導致這種情況?

還是有更可靠的建議方法?

更新。 我找到了問題的根源,並且可以重現。 這是可運行的示例代碼:

from bottle import route, run, response
import time
import sys
import threading
import queue

engineStartQueue = queue.Queue()

class EngineStarter(threading.Thread):

    def run(self):
        try:
            global engineStartQueue
            startParams = engineStartQueue.get_nowait()

            #let url handler return 
            engineStartQueue.put_nowait([200, "Starting..."])
            time.sleep(10.0)
        except Exception as e:
            fullerror = sys.exc_info()
            errorID = str(fullerror[0])
            errorMsg = str(fullerror[1])
            alertMessage = "%s, %s" %(errorID, errorMsg)
            engineStartQueue.push([500, alertMessage])


@route('/admin/start', method='POST')
def start():   
    try:
        global engineStartQueue
        engineStartQueue.put("Hello")
        starter = EngineStarter()
        starter.start()

        time.sleep(3.0)  #Give the EngineStarter instance a couple of seconds to read the queue and respond
        returnParams = engineStartQueue.get_nowait()

        response.status = returnParams[0]
        return(returnParams[1])
    except Exception as e:
        fullerror = sys.exc_info()
        errorID = str(fullerror[0])
        errorMsg = str(fullerror[1])
        returnStr = "Failed to start:  %s, %s" %(errorID, errorMsg)
        response.status = 500
        return returnStr

if __name__ == '__main__':
    run(host='localhost', port=8080)

這是一個瓶裝應用,具有開火和忘記REST的功能。 有URL處理程序,可線程化對象和全局可見隊列。

URL處理程序1-創建可線程對象的實例,EngineStarter 2-將“ Hello”傳遞到隊列3-啟動線程4-等待3秒並從EngineStarter線程獲取響應5-將http響應代碼返回到呼叫者

EngineStarter線程:1-讀取隊列2-如果線程不為空​​,則以http ok響應,否則返回500錯誤3-引擎啟動器線程現在等待10秒,以模擬服務器上長時間運行的后台任務

如果我在pydev調試器中啟動腳本,然后在未設置任何斷點的情況下調用處理程序,則3秒鍾后會收到http 200響應。 這意味着范圍是共享的。

如果在查看隊列之前設置斷點,則該斷點為空。 如果在查看隊列后設置了斷點,則get_nowait()會選擇“ Hello”。

似乎pydev調試器中的斷點正在某種程度上影響范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM