传递给同一个函数的多个线程的变量

Variable passed to multiple threads of the same function

我目前正在开发一个使用 dhook 将 webhook 发送到多个 Discord 的系统。

此函数用于调用发送 webhook 的函数。 webhooks 的长度是 2,它是一个列表的列表。

for hook in webhooks:
    thread.start_new_thread(send_hook,(hook, embed, tag))

这是send_hook函数:

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 行设置页脚时,插入到嵌入变量中的变量有时会发送到错误的 webhooks - 几乎就像它被过度使用一样。

举个例子:

这是我的网络挂钩列表:[["Webhook 1 text", "discordwebhook1"], ["Webhook 2 text", "discordwebhook1"]]

将会发生的是,在 discordwebhook1 的频道中,页脚会显示 "Webhook 1 text",但在 discordwebhoo2 的频道中,页脚会显示 "Webhook 1 text" as-出色地。

我已经尝试在 send_hook 函数中创建嵌入的新变量 - 但这也没有用(下面的代码)。

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)

感谢所有帮助!

谢谢

如何获得'embed'?请注意 'embed' 和 'tag' 总是传递给每个新创建的线程,如有必要,您需要对每个线程进行深度复制

from copy import deepcopy

for hook in webhooks:
    thread.start_new_thread(send_hook,(hook, deepcopy(embed), tag))

您正在经历 race condition。两个线程可以访问同一个变量,并且它们都在修改该变量。您的程序的结果取决于哪个程序首先到达更改变量的代码。

有两种可能的解决方案,具体取决于您希望如何解决问题:

  1. 如果您不需要所有线程共享相同的值,或者如果对象很小且复制成本低,请复制在传递变量之前,通过传递 deepcopy(embed) 而不是 embed - 请参阅 获取代码。

  2. 如果希望所有线程共享同一个值,或者如果复制对象的开销很大,则需要创建锁使用 my_lock = threading.Lock(),当你到达程序的竞争条件部分(即修改共享变量的部分)时,用上下文管理器包围它 with my_lock:,它在开始时获取锁returns 完成后锁定。例如:

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)