【问题标题】:Queue is blocking Main thread队列阻塞主线程
【发布时间】:2017-09-13 07:46:54
【问题描述】:

我有一个用于 3 个项目的 for 循环。在for 循环内,我为每个项目生成 15 个线程。这些都将数据返回到我的 GUI,但发生的是 for 循环执行,所有 3 个项目都运行完毕,并产生了 45 个线程。我正在尝试运行第一项,等到 15 个线程完成,然后运行第二项。我需要在不使用join() 的情况下完成所有这些操作。

我认为这可以通过queue 完成,但在阻止时遇到了麻烦。当我尝试以下操作时,它永远不会移动到第二组 15 个线程:

while True:
    try:
        data = q.get(False)
    except Query.Empty():
        data = None

这停止了阻塞问题,并使用 15 个线程中的每一个线程中执行的函数不断更新我的 GUI,但是一旦它们执行,它就会简单地结束并且不会继续 for 循环。这是有问题的循环:

def thing_1(names):
    def thready():
        print "Hello!"
        q.put("Done")
    for name in names:
        print "Working on " + name
        t1 = threading.Thread(target=thready)
        t1.start()
        # Then put 'while True' here

【问题讨论】:

    标签: python multithreading python-2.7 queue


    【解决方案1】:

    当活动线程数降至 1(假设您没有任何其他活动线程)时,通过打破while True 循环可以很容易地解决这个问题。试试

    while True:
        try:
            data = q.get(False)
        except Query.Empty():
            data = None
        if threading.active_count() == 1:
            break
    

    您可以改为使用与现在相同的循环体,但将 while 条件更改为

    while threading.active_count() > 1:
    

    【讨论】:

    • 您还可以考虑在 while 循环中添加一个小的(25 毫秒?)睡眠,以避免您的 GUI 线程占用过多的 CPU 时间。
    • 似乎是超出except 部分的问题。如果我用print "Hello!" 之类的简单语句替换您的新if 语句,它甚至不会打印。
    • 听起来您可能在代码中混淆了缩进,但示例上下文并不足以决定。 while 循环应该与上面的for 处于同一级别。通过插入一个print 调用来检查while 循环实际上是否按照您的想法运行。
    • while 必须在for 之内,否则在同时执行第 2 项和第 3 项时问题仍然存在。 Queue.Empty() 似乎没有引起注意。当我用基本的except Exception as e 替换时,示例print "Hello!" 有效。
    • 大概for的每次迭代都会启动一个线程,而names有15个条目,被调用了3次?如果你把while 放在for 里面,它会在你每次启动线程时运行。
    猜你喜欢
    • 2018-06-26
    • 2019-02-12
    • 1970-01-01
    • 2014-10-16
    • 2018-02-16
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多