thead.join()只有在所有线程完成后才没有帮助打印字符串



我当前正在尝试编写一个实现以下功能的功能:

  • 以随机顺序从列表"消息"中获取所有消息,同时确保没有重复。
  • 在延迟在1-10秒之间延迟随机数秒后打印它们。
  • 完成所有线程后,它将打印一个字符串"打印完成。您将在5秒内返回主菜单。"

但是,我遇到的问题是字符串"打印已经完成..."是在随机消息之间打印的,而不是在它们之后。

我的混乱源于以下事实:.join()方法非常适合类似功能。仅在所有线程完成后才打印字符串。它们之间的主要区别在于,另一个函数不进行任何随机输入。取而代之的是,它在一个名为" messages_and_times"的全局字典上迭代,其中键:值对来自消息的用户输入和秒数(用户输入由另一个函数处理)。

)。

下面您可以看到不起作用的函数option_3(),以及确实有效的函数option_2()。在最底部,我将包括整个代码以供进一步参考。

有人可以帮助我理解我在做什么错吗?

预先感谢您的时间和帮助。

P.S。clear()功能在每个输入后都可以清除终端显示。

非工作功能:

def option_3():
    clear()
    messages = ["message_1", "message_2", "message_3", "message_4", "message_5",
                "message_6", "message_7", "message_8", "message_9", "message_10"]
    print("Printing initialized:n")
    def threading_function(message, seconds):
        time.sleep(seconds)
        print(message)
    for message in messages:
        randomized_messages = []
        random_index = random.randint(0, len(messages) - 1)
        randomized_messages.append(messages.pop(random_index))
        for msg in randomized_messages:
            t = Thread(target=threading_function, args=(msg, random.choice(range(1,11))))
            t.start()

    t.join()
    time.sleep(0.5)
    print(
        "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
    time.sleep(5)
    main_menu()

工作功能:

def option_2():
    global messages_and_times
    clear()
    print("Printing initialized:n")
    def threading_function(message, seconds):
        time.sleep(seconds)
        print(message)
    for message, seconds in messages_and_times.items():
        t = Thread(target=threading_function, args=(message, seconds))
        t.start()
    t.join()
    time.sleep(0.5)
    print(
        "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
    time.sleep(5)
    main_menu()

整个main_menu()函数:

import os
import random
clear = lambda: os.system('cls')
messages_and_times = {}

def main_menu():
    def option_1():
        global messages_and_times
        clear()
        message = input(
            "Please type in a message you would like to add to the list:")
        clear()
        seconds = int(
            input("Please type in the time of delay for this message:"))
        messages_and_times[message] = seconds
        def create_dictionary():
            clear()
            answer = input(
                "Would you like to add another message? (yes/no)").lower()
            if answer == "yes":
                option_1()
            elif answer == "no":
                clear()
                print("You will now be returned to the main menu.")
                time.sleep(1.5)
                main_menu()
            else:
                clear()
                print("Please answer yes or no.")
                time.sleep(1.5)
                create_dictionary()
        create_dictionary()
    def option_2():
        global messages_and_times
        clear()
        print("Printing initialized:n")
        def threading_function(message, seconds):
            time.sleep(seconds)
            print(message)
        for message, seconds in messages_and_times.items():
            t = Thread(target=threading_function, args=(message, seconds))
            t.start()
        t.join()
        time.sleep(0.5)
        print(
            "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
        time.sleep(5)
        main_menu()
    def option_3():
        clear()
        messages = ["message_1", "message_2", "message_3", "message_4", "message_5",
                    "message_6", "message_7", "message_8", "message_9", "message_10"]
        randomized_messages = []
        print("Printing initialized:n")
        def threading_function(message, seconds):
            time.sleep(seconds)
            print(message)
        for message in messages:
            random_index = random.randint(0, len(messages) - 1)
            randomized_messages.append(messages.pop(random_index))
        for msg in randomized_messages:
            t = Thread(target=threading_function, args=(msg, random.choice(range(1,11))))
            t.start()

        t.join()
        time.sleep(0.5)
        print(
            "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
        time.sleep(5)
        main_menu()

    clear()
    selection = 0
    while selection == 0:
        print(("-" * 15) + "MAIN MENU" + ("-" * 15) + "n")
        print("1: Input a message and a corresponding time of delay before its display.")
        print("2: Print your customized list of messages.")
        print("3: Print random messages with random delays.n")
        selection = int(input(
            "Please select one of the options, by typing in the corresponding number:"))
        if selection == 1:
            option_1()
        elif selection == 2:
            option_2()
        elif selection == 3:
            option_3()
        else:
            clear()
            print("Please select from options 1 - 3.n")
            time.sleep(1.5)
            main_menu()

编辑(最终解决方案以供将来参考):

感谢Almog David的建议,这是我修改了我的功能以按预期工作的方式。我希望这有助于某人将来浏览解决方案。

option_2():

 def option_2():
    global messages_and_times
    clear()
    threads = []
    print("Printing initialized:n")
    def threading_function(message, seconds):
        time.sleep(seconds)
        print(message)
    for message, seconds in messages_and_times.items():
        t = Thread(target=threading_function, args=(message, seconds))
        t.start()
        threads.append(t)
    for t in threads:
        t.join()
    time.sleep(0.5)
    print(
        "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
    time.sleep(5)
    main_menu()

option_3():

def option_3():
        clear()
        messages = ["message_1", "message_2", "message_3", "message_4", "message_5",
                    "message_6", "message_7", "message_8", "message_9", "message_10"]
        threads = []
        print("Printing initialized:n")
        def threading_function(message, seconds):
            time.sleep(seconds)
            print(message)
        for message in messages:
            t = Thread(target=threading_function, args=(
                message, random.choice(range(1, 11))))
            t.start()
            threads.append(t)
        for t in threads:
            t.join()
        time.sleep(0.5)
        print(
            "nPrinting is finished. You will be returned to the main menu in 5 seconds.")
        time.sleep(5)
        main_menu()

问题是您只等待最后一个线程加入(因为't'变量在循环结束时持有最后一个创建的线程对象),因此联接函数在最后一个时返回线程已完成,程序继续。

即使在选项2上,我也能够通过提供:

来复制此错误
messages_and_times = {"message_0": 3,
                  "message_1": 3,
                  "message_2": 1}

上述配置的结果是:

message_2
Printing is finished. You will be returned to the main menu in 5 seconds.
message_0
message_1

您应该做的修复是:

threads = []
for message, seconds in messages_and_times.items():
    t = Thread(target=threading_function, args=(message, seconds))
    t.start()
    threads.append(t)
for t in threads:
    t.join()

最新更新