簡體   English   中英

確定線程是否完成的非阻塞方式?

[英]Non-blocking way to determine if thread is finished?

我有以下代碼:

import threading
import time

class TestWorker (threading.Thread):
    def __init__(self, threadID, name):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name

    def run(self):
        print "Starting " + self.name
        time.sleep(20)
        print "Exiting " + self.name
        # how do I let the calling thread know it's done?

class TestMain:
    def __init__(self):
        pass

    def do_work(self):
        thread = TestWorker(1, "Thread-1")
        thread.start()

    def do_something_else(self):
        print "Something else"

    def on_work_done(self):
        print "work done"

如何讓主線程知道TestWorker已經完成(調用on_work_done() ),而不像thread.join()那樣阻塞對do_something_else()調用?

你可以給你的線程實例一個可選的回調函數,當它完成時調用。
注意我添加了一個Lock來防止並發打印(它會阻塞)。

print_lock = threading.Lock()  # Prevent threads from printing at same time.

class TestWorker(threading.Thread):
    def __init__(self, threadID, name, callback=lambda: None):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.callback = callback

    def run(self):
        with print_lock:
            print("Starting " + self.name)
        time.sleep(3)
        with print_lock:
            print("Exiting " + self.name)
        self.callback()

class TestMain:
    def __init__(self):
        self.work_done = False

    def do_work(self):
        thread = TestWorker(1, "Thread-1", self.on_work_done)
        thread.start()

    def do_something_else(self):
        with print_lock:
            print("Something else")

    def on_work_done(self):
        with print_lock:
            print("work done")
        self.work_done = True

main = TestMain()
main.do_work()
while not main.work_done:
    main.do_something_else()
    time.sleep(.5)  # do other stuff...

print('Done')

輸出:

Starting Thread-1
Something else
Something else
Something else
Something else
Something else
Something else
Exiting Thread-1
work done
Done
import queue
import threading

class SThread(threading.Thread, queue.Queue):
    def __init__(self, queue_out: object):
        threading.Thread.__init__(self)
        queue.Queue.__init__(self)
        self.queue_out = queue_out
        self.setDaemon(True)
        self.start()

    def run(self):
        print('Thread start')
        while True:
            cmd = self.get()
            if cmd is None:
                break  # exit thread
            self.queue_out.put(cmd['target'](*cmd.get('args', ())), **cmd.get('kwargs', {}))
            self.task_done()
        print('Thread stop')

def testFn(a):
    print('+ %s' % a)
    return a

if __name__ == '__main__':
    print('main 1')
    # init
    queue_out = queue.Queue()
    thread = SThread(queue_out)

    # in
    for a in range(5): thread.put(dict(target=testFn, args=(a,)))

    thread.put(None)
    print('main 2')
    # out
    while True:
        try:
            print('- %s' % queue_out.get(timeout=3))
        except queue.Empty:
            break
    print('main 3')

輸出:

main 1
Thread start
main 2
+ 0
+ 1
+ 2
+ 3
+ 4
Thread stop
- 0
- 1
- 2
- 3
- 4
main 3
import threading
dt = {}
threading.Thread(target=dt.update, kwargs=dict(out=123)).start()

while 'out' not in dt:
    print('out' in dt)
print(dt)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM