[英]How to use same-name global variable if passed as None to a function?
[英]Variable passed to multiple threads of the same function
我目前正在开发一个使用 dhooks 将 webhook 发送到多个 Discord 的系统。
这是用于调用发送 webhook 的 function 的 function。 webhooks
的长度为 2,它是一个列表列表。
for hook in webhooks:
thread.start_new_thread(send_hook,(hook, embed, tag))
这是 send_hook function:
def send_hook(hook, embed, tag):
embed.set_footer(text="{} x Will".format(hook[0])) <-- This is the part where the error happens
webhook = Webhook(hook[1])
webhook.send(embed=embed)
我得到的错误是,当我在send_hook
的第 2 行设置页脚时,插入到 embed 变量中的变量有时会被发送到错误的 webhook - 几乎就像它被覆盖一样。
举个例子:
这是我的 webhook 列表: [["Webhook 1 text", "discordwebhook1"], ["Webhook 2 text", "discordwebhook1"]]
。
将会发生的情况是,在discordwebhook1
的通道中,页脚会显示“Webhook 1 text”,但在discordwebhoo2
的通道中,页脚也会显示“Webhook 1 text”。
我已经尝试在send_hook
function 中创建嵌入的新变量 - 但是这也不起作用(下面的代码)。
def send_hook(hook, embed, tag):
new_embed = embed
new_embed.set_footer(text="{} x Will".format(hook[0])) <-- This is the part where the error happens
webhook = Webhook(hook[1])
webhook.send(embed=new_embed)
我感谢所有帮助!
谢谢
你如何获得“嵌入”? 请注意,“嵌入”和“标签”始终传递给每个新创建的线程,如果需要,您需要对每个线程进行深度复制
from copy import deepcopy
for hook in webhooks:
thread.start_new_thread(send_hook,(hook, deepcopy(embed), tag))
您正在经历竞争状况。 两个线程可以访问同一个变量,并且它们都在修改该变量。 程序的结果取决于哪个程序首先到达更改变量的代码。
有两种可能的解决方案,具体取决于您希望如何解决问题:
如果您不需要所有线程共享相同的值,或者如果 object 小且复制成本低,请在传递之前复制您传递的变量,通过传递deepcopy(embed)
而不是embed
- 请参阅@user1438644 为代码发布的解决方案。
如果您希望所有线程共享相同的值,或者如果复制 object 的成本很高,则需要使用my_lock = threading.Lock()
创建一个锁,并且当您进入竞争条件部分时程序(即修改共享变量的部分),用with my_lock:
的上下文管理器包围它,它在开始时获取锁并在完成时返回锁。 例如:
import threading
my_lock = threading.Lock()
# your code here
for hook in webhooks:
threading.Thread(send_hook, args=(hook, embed, tag))
# more code here
def send_hook(hook, embed, tag):
# Ensure embed is only changed by one thread at a time
with my_lock:
print("Lock acquired")
embed.set_footer(text="hello world")
webhook = Webhook(hook[1])
webhook.send(embed=embed)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.