gpt4 book ai didi

python - 设置空闲线程/信令线程

转载 作者:太空狗 更新时间:2023-10-30 02:47:18 25 4
gpt4 key购买 nike

我正在使用 Python 和 wxPython 来编写应用程序。

我正在考虑实现此目的的方法可能不是最好的 - 如果是这种情况,请告诉我,因为我愿意重构。

现在,我有一个 GUI 表单。主程序开始点实例化 GUI 窗体的一个实例,然后运行 ​​wx.mainLoop(),这会导致应用程序的主初始线程在应用程序的生命周期内阻塞。

我们当然知道,当 UI 中发生事件时,UI 线程会为它们运行代码。

现在,我有另一个线程 - 一个工作线程。该线程需要闲置,然后当 UI 线程中发生某些事情时,例如单击一个按钮,我希望工作线程停止空闲并执行其他操作 - 运行一个函数,例如。

我现在无法想象这一点,但我可以看到随着应用程序变得越来越复杂,还必须在工作线程实际上忙于做某事时向它发出信号。

我对这个设置有两个问题:

  • 如何在不占用 CPU 时间的情况下让我的工作线程空闲?做类似 while True: pass 的事情会占用 CPU 时间,而类似 while True: time.sleep(0.1)不允许对事件做出即时 react 。
  • 向工作线程发出信号以执行某些操作的最佳方法是什么?我不希望 UI 线程执行某些操作,我希望 UI 线程向工作线程发出信号,表明它应该更改其正在执行的操作。理想情况下,我有一些方法让工作线程向 UI 本身注册回调,以便当单击按钮或发生任何其他 UI 事件时,工作线程会收到信号以更改其正在执行的操作。

  • 那么,这是实现这一目标的最佳方式吗?最好的方法是什么?

    谢谢!

    最佳答案

    第一:首先你真的需要一个后台线程来闲置吗?

    在大多数平台上,启动一个新线程的成本很低。 (除了在 Windows 和 Linux 上,它非常便宜。)那么,为什么不在需要时启动线程呢? (保留线程列表和保留单个线程一样容易,对吗?)

    或者,为什么不创建一个 ThreadPoolExecutor ,然后将作业提交给它,让执行程序担心它们何时运行以及在哪个线程上运行。任何时候您只要考虑“需要在不阻塞主线程的情况下运行的任务”而不是“需要等待工作的工作线程”,您的生活就会变得更轻松。在幕后,仍然有一个或多个工作线程在等待队列,或其他类似的东西,但那部分都是为您编写(并调试和优化)的。您只需要编写任务,它们只是常规函数。

    但是,如果你想编写显式的后台线程,你可以,所以我会解释一下。

    How can I make my worker thread idle without using up CPU time? … What's the best way to signal into the worker thread to do something?



    在值准备好之前空闲线程的方法是等待同步对象。在任何现代操作系统上,等待同步对象意味着操作系统停止为您提供任何 CPU 时间,直到该对象为您准备好。*

    您可以在 Threading 中看到各种不同的选项。模块文档,但在大多数情况下,最明显的使用方式是 Condition .然后向工作线程发送信号的方法是 notify Condition .

    然而,经常是 Queue 简单很多。等待 Queue ,只需调用其 get方法与 block=True .要通知另一个线程唤醒,只需 put关于 Queue 的东西. (在幕后, Queue 包含 listdeque 或其他集合, LockCondition ,所以你只需告诉它你想要做什么——检查一个值,阻塞直到有一个值,添加一个值——而不是处理等待和信号以及保护集合。)

    controlling UI elements in wxPython using threading的回答了解如何在两个方向上发出信号,从工作线程到 UI 线程,反之亦然。

    I'd have some way for the worker thread to register a callback with the UI itself, so that when a button is clicked or any other UI Event happens, the worker thread is signalled to change what it's doing.



    如果你愿意,你可以这样做。刚通过 self.queue.putdef callback(value): self.value = value; self.condition.notify()或者作为回调的任何东西,GUI 线程甚至不必知道回调正在触发另一个线程。

    事实上,这是一个非常好的设计,当您决定在内联和后台线程之间来回移动一些代码时,或者将其移到子进程而不是后台线程,或者其他任何时候,它可能会让您以后感到非常高兴。

    I can't envision this right now but I could see as the app gets more complex also having to signal the worker thread while it's actually busy doing something.



    但是如果它很忙,你想发生什么?

    如果你只想说“如果你闲着,醒来做这个任务;否则,捕获它,等你准备好了就做”,这正是 Queue ,或 Executor ,会自动为你做。

    如果你想说,“如果你闲着,就醒醒,否则,别担心”,那就是 ConditionEvent会做。

    如果你想说,“如果你闲着,醒来做这个,否则,取消你正在做的事情,然后做这个”,那就有点复杂了。您几乎需要让后台线程在繁忙时定期检查“interrupt_me”变量(并在其周围放置一个 Lock),然后您将设置该标志并通知 Condition ...虽然在某些情况下,您可以将空闲和忙碌的情况合并为一个 ConditionEvent (空闲时调用无限 wait(),忙时快速检查 wait(timeout=0))。

    * 在某些情况下——例如,Linux futex或 Windows CriticalSection — 在某些情况下,它实际上可能会占用一点 CPU 时间,因为这恰好是一个很好的优化。但关键是,在您准备好使用它之前,您不会要求任何 CPU 时间。

    关于python - 设置空闲线程/信令线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16472639/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com