繁体   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