Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 确定线程是否完成的非阻塞方式?_Python_Multithreading - Fatal编程技术网

Python 确定线程是否完成的非阻塞方式?

Python 确定线程是否完成的非阻塞方式?,python,multithreading,Python,Multithreading,我有以下代码: 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 "St

我有以下代码:

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\u work\u done()
),而不阻止对
do\u other()
的调用,就像
thread.join()
那样?

你可以给你的线程实例一个可选的回调函数,在它完成时调用。
import threading
dt = {}
threading.Thread(target=dt.update, kwargs=dict(out=123)).start()

while 'out' not in dt:
    print('out' in dt)
print(dt)
注意:我添加了一个
,以防止并发打印(这会阻止打印)

输出:

开始线程-1
别的
别的
别的
别的
别的
别的
退出线程-1
完成的工作
多恩
输出:


. 或者您正在寻找基于事件的东西?这难道不意味着轮询线程并通过这样做仍然阻止主线程吗?所以您的问题实际上是“线程完成后如何调用函数”,而不是“如何确定线程是否完成”?在这种情况下,您需要触发某种事件,或者只调用
TestMain.on\u work\u done()
中的
TestWorker.run
。如果我使用回调,工作线程不会在\u work\u done上执行,因此无法关闭(on\u work\u done本身可能需要一段时间)。基于事件听起来不错,但我还没有找到一个好的资源来匹配我在Python方面的有限经验。如果你的经验有限,为什么要在线程上胡闹?只是你的爱。dt={}除非我轮询或以其他方式使用超时来读取它的值,否则while循环会阻塞主线程,并在工作线程的运行期间未经检查地运行,这不会很好,然后在TestWorkerWorks中使用in/out queue.queue()-queue.task_done(),但我不知道在回调中从何处开始另一个线程(可能发生在实际应用程序中),该线程是MainThread还是TestWorker的子线程?(这有什么关系?)我不确定,但我认为这并不重要,除了可能与它是否是守护进程线程(其初始值是从创建线程继承的)有关如果我的答案解决了你的问题,请考虑接受它。(见)我会,不用担心:谢谢你的时间和答案!
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')
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