【问题标题】:How to run a thread alongside telethon client如何在 Telethon 客户端旁边运行线程
【发布时间】:2020-04-04 16:04:04
【问题描述】:

我愿意根据时间使用telethon 发送一些消息,我的方法是编写一个函数并在一个新线程中启动它并检查我必须每秒发送哪些消息。即如下所示:

async def function():
  while True:
    time = datetime.datetime.now()
    await send_some_messages(time)

但是 Telethon 需要我在它运行的同一个循环上等待。我知道我可以使用client.run_until_disconnected() 获取当前循环,但我很困惑我该怎么做。

如果您能给我一个在不同线程中运行此函数的方法,但仍然能够使用 Telethon 客户端发送消息,那就太好了。

【问题讨论】:

  • 为什么要在线程中运行它?

标签: python-3.x telethon


【解决方案1】:

在使用asyncio 时,您不需要使用线程,也不必使用client.run_until_disconnected()。所做的只是保持事件循环运行,直到客户端断开连接。只要您运行事件循环,Telethon 就可以正常工作。

# Create client
client = ...

# Do whatever with the client
@client.on(...)
async def handler(event):
    ...

async def main():
    while True:
        # Do whatever (check if now is time to send messages, for example)
        ...

        # Yielding control back to the event loop here (with `await`) is key.
        # We're giving an entire second to it to do anything it needs like
        # handling updates, performing I/O, etc.
        await asyncio.sleep(1)

client.loop.run_until_complete(main())

保持事件循环运行的其他方法是使用loop.run_forever,不要忘记您可以asyncio.create_task 或等待其中的许多... 我鼓励您阅读asyncio 文档。就像threading 一样,该文档值得查看以了解如何使用它。


附带说明,如果您真的需要线程(例如,您正在执行 CPU 密集型工作),asyncio 也可以为您提供支持。但这些都不是 Telethon 特有的。

如果您想更好地了解 asyncio 的工作原理(可能对您有所帮助),请参阅 An Introduction to Asyncio

不用说,有更好的方法来检查何时发送消息(使用堆和事件,睡眠直到下一次到期或另一个最大值,而不仅仅是一秒),但这应该让你开始。

【讨论】:

  • 对于 CPU 密集型工作,您应该使用单独的进程而不是线程,至少在 CPython 中(来自python.org 的 Python 实现)。在 CPython 中,一次只有一个线程可以执行 Python 字节码。
  • @RolandSmith 好吧,是的。但实际上,我的意思是任何阻塞一段时间的东西都应该至少放在一个线程中,这通常比整个进程更容易和更轻量级。这仍然会让asyncio 运行并且不会阻塞整个事件循环。
  • 是否有任何方法可以修改代码,以使新传入消息的事件处理程序仍会执行,即使脚本正在运行 while 循环的任何部分?我注意到如果脚本正在执行 Dowhatever 部分,那么此时收到的所有消息都不会被处理。
  • 只要您足够频繁地将控制权交给事件循环,您仍然应该收到消息。不过,也许您希望 loop.run_in_executor 将密集的内容放在另一个线程中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
  • 2021-08-06
  • 1970-01-01
相关资源
最近更新 更多