【问题标题】:Thread got stuck on first join线程在第一次加入时卡住了
【发布时间】:2021-12-31 11:49:19
【问题描述】:

我正在使用多线程,总共有 5 个线程,在执行t.join() 时,只有一个线程结束,其余线程继续运行。有谁知道为什么?

我的脚本:

if __name__ == "__main__":
    args.debug = True
    for x in args.list:
        args.threads.append(threading.Thread(target=RD.stream, args=(x,)))
    args.threads.append(threading.Thread(target=RD.subs_stream))
    args.threads.append(threading.Thread(target=TW.stream))
    args.threads.append(threading.Thread(target=pooling_stream))
    start_threads()
    while True:
        time.sleep(1)
        if not args.update:
            print("Update")
        else:
            for i in range(len(args.threads)):
                try:
                    if args.threads[i].is_alive():
                        print(f"before Stopped Thread {str(args.threads[i])}")
                        args.threads[i].join()
                        print(f"after Stopped Thread {str(args.threads[i])}")
                    else:
                        print(i)
                except Exception as e:
                    print(e)

输出是:

Started Thread <Thread(Thread-1, initial)>
Started Thread <Thread(Thread-2, initial)>
Started Thread <Thread(Thread-3, initial)>
Started Thread <Thread(Thread-4, initial)>
Started Thread <Thread(Thread-5, initial)>
Update
Update
Update
Update
before Stopped Thread <Thread(Thread-1, started 19972)>

【问题讨论】:

  • 这取决于线程中调用的函数。他们会回来吗?如果没有,您将永远等待。
  • 他们不会回来,这是一条永远运行的流。关于易于实施的任何建议? @tdelaney
  • 您是否正在寻找终止线程的方法?这些流可能有一些方法调用来终止/关闭它们。线程将等待接收或其他什么,但如果您调用这些终止方法,线程函数可能会收到错误,您可以使用它从线程中返回。如果您不关心干净的关闭,您可以将线程标记为daemon在启动它们之前。然后直接退出程序而不进行连接。
  • 你能试着在我发布的脚本上写一个例子吗?也许我可以使用daemon@tdelaney
  • 我无法编写关闭流的示例,因为我不知道那个 API 是什么。我可以写出硬退出案例。

标签: python python-3.x multithreading


【解决方案1】:

您的线程正在调用永远运行的函数,因此连接将永远等待。如果这些函数有一个 API 可以让您终止操作,那么您可以在主线程中调用它们。必须更新线程函数以处理错误并返回。请注意,默认情况下,python 将在退出时 join 线程。除非您在加入后需要做某事(或想要调试消息),否则您不必自己这样做。举个粗略的例子,

def stop_threads():
    # assuming these things have a "close" method to terminate them
    RD.stream.close()
    RD.subs_stream.close()
    etc...

if __name__ == "__main__":
    args.debug = True
    for x in args.list:
        args.threads.append(threading.Thread(target=RD.stream, args=(x,)))
    args.threads.append(threading.Thread(target=RD.subs_stream))
    args.threads.append(threading.Thread(target=TW.stream))
    args.threads.append(threading.Thread(target=pooling_stream))
    start_threads()
    while True:
        time.sleep(1)
        if not args.update:
            print("Update")
        else:
            stop_threads()
            break

如果您不关心线程会发生什么,只想在updateTrue 时退出,您可以将线程设置为“守护进程”,然后退出应用程序。通常,python 会跟踪线程并在您终止时执行自己的连接。 daemon 标志告诉 python 不要那样做。退出吧。

if __name__ == "__main__":
    args.debug = True
    for x in args.list:
        args.threads.append(threading.Thread(target=RD.stream, args=(x,)), daemon=True)
    args.threads.append(threading.Thread(target=RD.subs_stream), daemon=True)
    args.threads.append(threading.Thread(target=TW.stream), daemon=True)
    args.threads.append(threading.Thread(target=pooling_stream), daemon=True)
    start_threads()
    while True:
        time.sleep(1)
        if not args.update:
            print("Update")
        else:
            break

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多