【问题标题】:How to run an infinite loop without blocking the main thread in Python?如何在不阻塞 Python 主线程的情况下运行无限循环?
【发布时间】:2018-04-01 02:29:48
【问题描述】:

我在一个类中有一个方法,它打开到 API 的连接,然后监听更改。监听更改是使用无限 for 循环完成的,该循环从库中的方法接收事件,用于我正在使用的 API 连接。唯一的问题是无限循环阻塞了需要运行其他东西的主线程。我尝试使用线程,但是 for 循环需要访问我的类中的变量来设置从 API 接收到的更改。我需要一种方法来运行这个无限循环而不阻塞主线程,但仍然能够在主线程的类中设置类变量。

这是需要运行的循环:

for event in events():
        event_type = event.event
        print(event_type)
        if event_type == 'open':
            pass
        elif event_type == 'put':
            # this sets the class variable
            self._status = json.loads(event.data)
        elif event_type == 'auth_revoked':
            raise AuthorizationError(None, msg='The API authorization has been revoked')
        elif event_type == 'error':
            raise APIError(None, msg=event.data)

【问题讨论】:

  • 展示相关代码!
  • @KlausD.添加了循环代码

标签: python multithreading infinite-loop


【解决方案1】:

这是一个棘手的问题。

一种方法是在单独的线程中运行无限循环,并为该线程设置线程安全机制以与主线程通信(例如,通过使用Queues 在线程中来回发送数据-safe 方式,或mutexes 以确保一个线程不会在另一个线程使用数据时修改数据)。

另一种方法是以非阻塞方式使用库的 API,以便您可以将其与主线程已经使用的任何事件循环集成。这是否可能在很大程度上取决于您的库提供给您使用的 API;您可能想联系该库的作者(或者可能是他们的开发人员的邮件列表,如果他们有的话)并询问他们是否有推荐的方法来处理这种情况。

第三种方法(在您的情况下可能可行,也可能不实用)是运行无限循环,但在无限循环的每次迭代中,调用一个运行主线程正常事件循环的一次迭代的函数。 (或相反亦然)。这样,每个代码库都可以运行其代码库的一次迭代,然后另一个代码库可以运行一次迭代,以此类推,无限期地。

【讨论】:

  • 不检查队列中的项目需要使用循环吗?
  • 它可能会,也可能不会......但只要它不需要无限期地阻塞或循环(并且它不需要),那么检查队列可以与保持主线程的兼容处理的其他职责。
  • 你有没有无限循环的例子?
  • 当然——只需在主线程事件循环的每次迭代中调用 the_queue.get(False) 一次。如果调用返回数据项,请处理它,否则继续您的业务并尝试在事件循环的下一次迭代中再次调用它。 (如果你的主线程的事件循环是基于时间的,这就是所有必要的;如果它是严格基于事件的,OTOH,你还需要一些机制来唤醒你的主线程从 select() 或任何它阻塞in; 在那种情况下,我发现在连接的套接字对上发送一个虚拟字节效果很好)
  • 我的主线程没有事件循环。这是图书馆的代码。主线程是用户的代码。
猜你喜欢
  • 2021-04-13
  • 1970-01-01
  • 2022-07-01
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 2012-10-03
相关资源
最近更新 更多