是蟒蛇的队列。Queue.put() 方法异步?



如果我以worker身份运行具有以下函数的线程,

q = queue.Queue()
def worker():
while True:
t = {}
for i in range(3):
t['a'] = i
q.put(t)

队列中填充了完全相同的字典,即{'a': 2}而不是序列{'a': 0}, {'a': 1}, {'a': 2}。我认为这是因为put()方法在 for 循环完成后运行,并且i的最后一个值为 2。我的解释对吗?

现在,如果我在 for 循环中移动字典的实例化,

def worker():
while True:
for i in range(3):
t = {'a': i}
q.put(t)

队列将填充所需的序列。我的解释是,首先,我在内存中创建一个字典对象,然后开始一个 for 循环并重新分配其值 3 次,但put()调用发生在循环完成后。在第二个实例中,我在 for 循环的每次迭代中创建一个新的字典对象,因此当循环后发生put()调用时,它们使用自己的键值对访问字典的 3 个不同实例。

谁能阐明这里幕后发生的事情?

我的解释正确吗?

您观察到这种行为是因为您一直在修改相同的对象

让我们把队列/线程放在一边,运行一个简化的代码,并有一些prints来理解发生了什么

t = {}
l = []
for i in range(3):
t['a'] = i
l.append(t)
print(l)
t['a'] = 20
print(l)
print(map(id, l))
[{'a': 2}, {'a': 2}, {'a': 2}]
[{'a': 20}, {'a': 20}, {'a': 20}]
# they are all the same!
[4474861840, 4474861840, 4474861840]

所以它与我们线程/队列无关 - 你只是添加同一个对象 3 次。

现在,如果我在 for 循环中移动字典的实例化

在这种情况下,您每次都会创建一个新对象,如以下代码所示:

l = []
for i in range(3):
t = {}
t['a'] = i
l.append(t)
print(l)
t['a'] = 20
print(l)
print(map(id, l))
[{'a': 0}, {'a': 1}, {'a': 2}]
[{'a': 0}, {'a': 1}, {'a': 20}]
# they are all different!
[4533475600, 4533502592, 4533502872]

所以这里没有魔法

回到你的问题

这是你可能感兴趣的:">是python的队列。Queue.put() 线程安全?这意味着全局变量q可以安全地由多个并发线程访问。 答案是肯定的 - 它是线程安全的

队列

模块实现多生产者、多使用者队列。它 在线程编程中特别有用,当信息必须 在多个线程之间安全地交换。此队列类 模块实现所有必需的锁定语义

在第一个示例中,您将相同的字典放入队列三次。这与队列无关。你会发现list.append也有同样的行为。

最新更新