Python未绑定对象的影响及多线程中Queue对象重新赋值后的引用问题
关于Python线程与队列对象引用的问题解答
首先直接给你结论:每一对线程都会牢牢持有启动时传入的原始队列对象,完全不受后续myQueue变量重新赋值的影响,你想要的“每对线程共享唯一队列”的目标其实已经实现了。
核心原理:Python的变量与对象是分离的
在Python里,变量(比如myQueue)其实只是一个指向对象的“引用标签”,而非对象本身。当你执行myQueue = queue.Queue()时,是先创建一个新的Queue对象,再让myQueue这个标签指向它。
启动线程时,args=(myQueue,)是把当前myQueue指向的Queue对象的引用复制了一份传递给线程函数的参数。这时候就算你之后把myQueue指向新的Queue对象,旧的Queue对象依然存在——因为那两个线程的函数参数还在引用它,它不会变成“未绑定状态”。
针对你的场景逐一解答
旧Queue对象的变化:
只要启动的线程还在运行,旧Queue对象就会被线程的参数引用着,不会被Python的垃圾回收机制回收。只有当这两个线程都结束运行、不再有任何引用指向这个旧Queue时,它才会被回收。线程使用的队列是否会更新:
绝对不会。每个线程在启动时就拿到了对应Queue对象的独立引用,之后无论外部的myQueue变量怎么变更,线程内部使用的都是一开始传入的那个队列实例。所以你的循环里,每一次迭代创建的一对线程,都会共享属于自己的唯一队列,和其他迭代的线程完全隔离。
验证小例子
你可以打印每个队列的唯一ID来确认,修改后的代码如下:
import queue, threading def getFromQueue(myQueue): while True: item = myQueue.get() if item is None: # 加停止信号避免线程无限循环 break print(f"从队列ID {id(myQueue)} 获取到: {item}") def putInQueue(myQueue, items): for item in items: myQueue.put(item) myQueue.put(None) # 发送停止信号 msgList = [["消息组1-1", "消息组1-2"], ["消息组2-1", "消息组2-2"]] for msg in msgList: myQueue = queue.Queue() print(f"为当前线程对创建了队列ID: {id(myQueue)}") threading.Thread(target=getFromQueue, args=(myQueue,)).start() threading.Thread(target=putInQueue, args=(myQueue, msg)).start()
运行后你会看到,每对线程打印的队列ID和循环中创建的队列ID完全一致,证明它们确实在使用各自的独立队列。
内容的提问来源于stack exchange,提问作者eng3
相关产品推荐
相关产品推荐

