如何在 Python 中传递并运行回调方法

发布于 2024-11-25 12:34:11 字数 524 浏览 1 评论 0原文

我有一个管理器(主线程),它创建其他线程来处理各种操作。 我希望我的经理在它创建的线程结束时(当 run() 方法执行完成时)收到通知。

我知道我可以通过使用 Thread.isActive() 方法检查所有线程的状态来做到这一点,但轮询很糟糕,所以我想收到通知。

我正在考虑为线程提供一个回调方法,并在 run() 方法的末尾调用此函数:

class Manager():
    ...
    MyThread(self.on_thread_finished).start() # How do I pass the callback

    def on_thread_finished(self, data):
        pass
    ...

class MyThread(Thread):
    ...
    def run(self):
        ....
        self.callback(data) # How do I call the callback?
    ...

谢谢!

I have a Manager (main thread), that creates other Threads to handle various operations.
I would like my Manager to be notified when a Thread it created ends (when run() method execution is finished).

I know I could do it by checking the status of all my threads with the Thread.isActive() method, but polling sucks, so I wanted to have notifications.

I was thinking of giving a callback method to the Threads, and call this function at the end of the run() method:

class Manager():
    ...
    MyThread(self.on_thread_finished).start() # How do I pass the callback

    def on_thread_finished(self, data):
        pass
    ...

class MyThread(Thread):
    ...
    def run(self):
        ....
        self.callback(data) # How do I call the callback?
    ...

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谈场末日恋爱 2024-12-02 12:34:11

线程不能调用管理器,除非它有对管理器的引用。实现这一点的最简单方法是管理器在实例化时将其交给线程。

class Manager(object):
    def new_thread(self):
        return MyThread(parent=self)
    def on_thread_finished(self, thread, data):
        print thread, data

class MyThread(Thread):

    def __init__(self, parent=None):
        self.parent = parent
        super(MyThread, self).__init__()

    def run(self):
        # ...
        self.parent and self.parent.on_thread_finished(self, 42)

mgr    = Manager()
thread = mgr.new_thread()
thread.start()

如果您希望能够分配任意函数或方法作为回调,而不是存储对管理器对象的引用,那么由于方法包装器等,这会变得有点问题。设计回调很困难,因此它会获取对管理器和线程的引用,这正是您想要的。我为此工作了一段时间,但没有想出任何我认为有用或优雅的东西。

The thread can't call the manager unless it has a reference to the manager. The easiest way for that to happen is for the manager to give it to the thread at instantiation.

class Manager(object):
    def new_thread(self):
        return MyThread(parent=self)
    def on_thread_finished(self, thread, data):
        print thread, data

class MyThread(Thread):

    def __init__(self, parent=None):
        self.parent = parent
        super(MyThread, self).__init__()

    def run(self):
        # ...
        self.parent and self.parent.on_thread_finished(self, 42)

mgr    = Manager()
thread = mgr.new_thread()
thread.start()

If you want to be able to assign an arbitrary function or method as a callback, rather than storing a reference to the manager object, this becomes a bit problematic because of method wrappers and such. It's hard to design the callback so it gets a reference to both the manager and the thread, which is what you will want. I worked on that for a while and did not come up with anything I'd consider useful or elegant.

酷炫老祖宗 2024-12-02 12:34:11

这样做有什么问题吗?

from threading import Thread

class Manager():
    def Test(self):
        MyThread(self.on_thread_finished).start()

    def on_thread_finished(self, data):
        print "on_thread_finished:", data

class MyThread(Thread):
    def __init__(self, callback):
        Thread.__init__(self)
        self.callback = callback

    def run(self):
        data = "hello"
        self.callback(data)

m = Manager()
m.Test() # prints "on_thread_finished: hello"

Anything wrong with doing it this way?

from threading import Thread

class Manager():
    def Test(self):
        MyThread(self.on_thread_finished).start()

    def on_thread_finished(self, data):
        print "on_thread_finished:", data

class MyThread(Thread):
    def __init__(self, callback):
        Thread.__init__(self)
        self.callback = callback

    def run(self):
        data = "hello"
        self.callback(data)

m = Manager()
m.Test() # prints "on_thread_finished: hello"
横笛休吹塞上声 2024-12-02 12:34:11

如果您希望主线程等待子线程完成执行,那么最好使用某种同步机制。如果只是在一个或多个线程完成执行时收到通知,则 条件就足够了:

import threading

class MyThread(threading.Thread):
    def __init__(self, condition):
        threading.Thread.__init__(self)
        self.condition = condition

    def run(self):
        print "%s done" % threading.current_thread()
        with self.condition:
            self.condition.notify()


condition = threading.Condition()
condition.acquire()

thread = MyThread(condition)
thread.start()

condition.wait()

但是,使用 Queue 可能更好,因为它可以处理多个工作线程容易一点。

If you want the main thread to wait for children threads to finish execution, you are probably better off using some kind of synchronization mechanism. If simply being notified when one or more threads has finished executing, a Condition is enough:

import threading

class MyThread(threading.Thread):
    def __init__(self, condition):
        threading.Thread.__init__(self)
        self.condition = condition

    def run(self):
        print "%s done" % threading.current_thread()
        with self.condition:
            self.condition.notify()


condition = threading.Condition()
condition.acquire()

thread = MyThread(condition)
thread.start()

condition.wait()

However, using a Queue is probably better, as it makes handling multiple worker threads a bit easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文