python:使用Queue将字典传递给其他线程

我正在使用Queue将字典传递给其他线程。 我期望收到两个不同的字典,但实际上我两次收到相同的字典。 我可以制作一个Deepcopy来解决问题,但是有没有比每次都进行Deepcopy更好的方法了?

import threading 
from queue import Queue
import time
import copy
q = Queue()

def put(q): 
    d = {}
    d[1] = 2
    print(' send d = {}'.format(d))
    q.put(d)
    # d = copy.deepcopy(d) # uncomment this line to fix the problem
    d.pop(1)
    print(' send again d = {}'.format(d))
    q.put(d)

def get(q): 
    d = q.get()
    print(' received d = {}'.format(d))
    d = q.get()
    print(' received again d = {}'.format(d))

if __name__ == "__main__": 
    t1 = threading.Thread(target=put,args=(q,)) 
    t2 = threading.Thread(target=get,)) 
    t1.start() 
    t2.start() 
    t1.join() 
    t2.join() 
    print("Done!") 
dhtz124 回答:python:使用Queue将字典传递给其他线程

问题是您要修改要放入队列的同一词典。这里的简单解决方案是直接创建一个新的解决方案。这是修改后的代码...

import threading
from queue import Queue
q = Queue()

def put(q): 
    d = {1:2}
    print(' send d = {}'.format(d))
    q.put(d)
    d = {3:4}
    print(' send again d = {}'.format(d))
    q.put(d)

def get(q):
    d = q.get()
    print(' received d = {}'.format(d))
    d = q.get()
    print(' received again d = {}'.format(d))

if __name__ == "__main__":
    t1 = threading.Thread(target=put,args=(q,))
    t2 = threading.Thread(target=get,)) 
    t1.start() 
    t2.start() 
    t1.join() 
    t2.join() 
    print("Done!")

从技术上讲,原始代码中包含竞争条件。 pop在队列有机会发送并被其他线程打印之前被执行。

,

您的代码没有问题。这实际上是正确的行为。 在接收方线程收到第一条消息之前,您实际上已经修改了字典。这就是为什么您在接收线程中两次收到空字典的原因。 在修改字典之前,我只是模拟了一个delay(2sec)。现在您可以看到接收器线程同时处于两种状态。

import threading
from queue import Queue
import time
import copy
q = Queue()

def put(q):
    d = {}
    d[1] = 2
    print('send d = {}'.format(d))
    q.put(d)
    # d = copy.deepcopy(d) # uncomment this line to fix the problem
    #Add a 2 sec delay to allow other thread to receive.
    time.sleep(2)
    d.pop(1)
    print(' send again d = {}'.format(d))
    q.put(d)

def get(q):
    d = q.get()
    print(' received d = {}'.format(d))
    d = q.get()
    print(' received again d = {}'.format(d))

if __name__ == "__main__":
    t1 = threading.Thread(target=put,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print("Done!")

这是输出

发送d = {1:2}
 收到d = {1:2}
 再次发送d = {}
 再次收到d = {}
完成!

在消息传递上下文中,通常有2条消息指向deepcopy or dict(d) 可以实现的2个不同对象。

希望这会有所帮助。

,

添加线程事件,当您完成工作后,该事件将立即继续: 第一次打印后设置exit_thread.set()。您的第二个电话要等到第一个电话结束后才能进行。它立即结束,除了等待第一个呼叫结束之外没有实际的等待时间,因此会立即继续。这是完成您的工作的最快方法。我希望这会有所帮助!

thresholds[{order(v <- unlist(Map(`[`,thresholds,2)))}[!duplicated(v)][c(3,1,2)]]
# [[1]]
# [[1]]$color
# [1] "red"
# 
# [[1]]$value
# [1] 100
# 
# 
# [[2]]
# [[2]]$color
# [1] "green"
# 
# [[2]]$value
# [1] 1
# 
# 
# [[3]]
# [[3]]$color
# [1] "blue"
# 
# [[3]]$value
# [1] 50
本文链接:https://www.f2er.com/3140493.html

大家都在问