本文介绍了如何避免等待线程完成执行 - Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Python 中定义了以下结构 -

I have the following structure defined in Python -

有两个线程.每个线程垂直向下扫描分支并打印其值.到达该分支的末端时,它会沿水平轴向前移动一步.例如,Thread1 将打印 a1、a2 和 a3.同时,线程 2 将扫描 b1.当两个线程都执行完毕后,线程1会跳转到B块,线程2会跳转到C块执行相同的处理.

There are two threads. Each thread scans the branch vertically downwards and prints its value. On reaching the end of that branch, it moves a step ahead along the horizontal axis. Like, Thread1 will print a1, a2 and a3. At the same time, Thread 2 will scan b1. When both the thread finish execution, Thread 1 will jump to block B and Thread 2 will jump to block C to carry out the same process.

当所有块都完成后,该过程又从头开始.我已经为此编写了一个脚本 -

When all the blocks are done, the process starts again from the beginning. I have written a script for the same -

def printTags(DevObj):
    if DevObj == None:
        return -1
    TagObj = DevObj.tagPointer
    while TagObj != None:
        time.sleep(5)
        print TagObj.id
        TagObj = TagObj.nextTag

import threading, thread

# temp1 points to Block A.
# temp2 points to Block B.

while True:
    t1 = threading.Thread(target=printTags, args=(temp1,))
    t2 = threading.Thread(target=printTags, args=(temp2,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    if temp1.nextDevice != None:
        temp1 = temp1.nextDevice
    else:
        temp1 = start.nextDevice

    if temp2.nextDevice != None:
        temp2 = temp2.nextDevice
    else:
        temp2 = start.nextDevice

但是,您可以看到,当线程在块 A 和 B 上工作时,线程 1 将比线程 2 花费更多时间,因为它必须打印更多值.正因为如此,线程 2 会在一段时间内保持未使用状态.我想避免这种空闲时间.我怎么能这样做?

However, you can see that when the threads are working on block A and B, Thread 1 will take more time than Thread 2 as it has to print more values. Because of this, Thread 2 remains unused for some time. I want to avoid this idle time. How can I do so?

推荐答案

你可以采取不同的方法,但我想指出其中的两个:

There are different approaches you can take, but I would like to point out two of them:

首先,使用信号量,这个和你的代码一样接近,但实际上并不可取:

First, use Semaphore, this one as close as your code but it is not preferable really:

from threading import Semaphore

def printTags(DevObj, s):
    ...
    s.release()
    ...

import threading, thread

# temp1 points to Block A.
# temp2 points to Block B.


s = Semaphore(0)
threads = [
    threading.Thread(target=printTags, args=(THING_TO_DO,s))
    for THING_TO_DO in THINGS_TO_DO
]
for t in threads:
    t.start()

while True:
    s.aquire()
    for t in threads:
        # give more work

更优选的选择是使用生产者/消费者模式:

More preferred option is to use producer/consumer pattern:

from threading import Semaphore

STOP = object()

def printTags(queue):
    while True:
        thing_to_process = queue.get()
        if thing_to_process is STOP:
            return
        else:
            #process

import threading, thread

# temp1 points to Block A.
# temp2 points to Block B.

THREAD_COUNT = 2
s = Semaphore(0)
threads = [
    threading.Thread(target=printTags, args=(queue,))
    for _ in xrange(THREAD_COUNT)
]

for thing in things:
    queue.put(thing)
for _ in xrange(THREAD_COUNT):
    queue.put(STOP)

for t in threads:
    t.start()

这篇关于如何避免等待线程完成执行 - Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 05:48