我正在使用 python-telegram-bot 库创建一个 Telegram 机器人,它能够应答消息,同时每 X 秒运行一次后台任务,如果满足条件,则发送 Telegram 消息。
我面临一个问题,每次满足条件并且代码发送消息时,都会创建一个新线程。我尝试隔离所有内容并提供了以下示例代码:
import asyncio
import logging
import threading
from telegram.ext import Application
TELEGRAM_TOKEN = "bot_token_here"
TELEGRAM_CHAT_ID = "telegram_chat_id_here"
async def work(application):
while True:
logging.info(f"=== There are: {threading.active_count()} threads. 1 ===")
await application.bot.send_message(chat_id=TELEGRAM_CHAT_ID, text="test")
logging.info(f"=== There are: {threading.active_count()} threads. 2 ===")
await asyncio.sleep(5)
threads = threading.enumerate()
for thread in threads:
try:
logging.info(f"Thread name: {thread.name} - alive: {thread.is_alive()} - daemon: {thread.daemon}")
except Exception as e:
logging.error(f"Error: {e}")
def main()->None:
application = Application.builder().get_updates_http_version('1.1').http_version('1.1').token(TELEGRAM_TOKEN).build()
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(work(application))
loop.close()
if __name__ == "__main__":
main()
输出如下:
2023-08-11 09:41:55,328 - root - INFO - === There are: 1 threads. 1 ===
2023-08-11 09:41:55,804 - root - INFO - === There are: 2 threads. 2 ===
2023-08-11 09:42:00,811 - root - INFO - Thread name: MainThread - alive: True - daemon: False
2023-08-11 09:42:00,812 - root - INFO - Thread name: ThreadPoolExecutor-0_0 - alive: True - daemon: True
2023-08-11 09:42:00,812 - root - INFO - === There are: 2 threads. 1 ===
2023-08-11 09:42:01,057 - root - INFO - === There are: 3 threads. 2 ===
2023-08-11 09:42:06,063 - root - INFO - Thread name: MainThread - alive: True - daemon: False
2023-08-11 09:42:06,063 - root - INFO - Thread name: ThreadPoolExecutor-0_0 - alive: True - daemon: True
2023-08-11 09:42:06,063 - root - INFO - Thread name: ThreadPoolExecutor-0_1 - alive: True - daemon: True
2023-08-11 09:42:06,063 - root - INFO - === There are: 3 threads. 1 ===
2023-08-11 09:42:06,286 - root - INFO - === There are: 4 threads. 2 ===
...
等等...
如果我删除
await asyncio.sleep(5)
行,我会得到:
2023-08-11 09:32:50,957 - root - INFO - === There are: 1 threads. 1 ===
2023-08-11 09:32:51,268 - root - INFO - === There are: 2 threads. 2 ===
2023-08-11 09:32:51,268 - root - INFO - Thread name: MainThread - alive: True - daemon: False
2023-08-11 09:32:51,268 - root - INFO - Thread name: ThreadPoolExecutor-0_0 - alive: True - daemon: True
2023-08-11 09:32:51,268 - root - INFO - === There are: 2 threads. 1 ===
2023-08-11 09:32:51,403 - root - INFO - === There are: 2 threads. 2 ===
2023-08-11 09:32:51,403 - root - INFO - Thread name: MainThread - alive: True - daemon: False
2023-08-11 09:32:51,403 - root - INFO - Thread name: ThreadPoolExecutor-0_0 - alive: True - daemon: True
2023-08-11 09:32:51,403 - root - INFO - === There are: 2 threads. 1 ===
2023-08-11 09:32:51,502 - root - INFO - === There are: 2 threads. 2 ===
所以这次总是 2 个线程。
我需要我的
work
函数在下一次执行之前等待,但随后我得到了这个无限线程生成器...
我还测试了删除
send_message
行,并单独保留 asyncio.sleep(5)
,但它不会创建新线程,仅结合两个函数。
任何人都可以帮助我理解我做错了什么或者这是否是预期的?
回答我自己的问题...
经过进一步测试,问题似乎出在使用的Python版本(3.7)上。我升级到 3.11,问题现在消失了,它现在只创建了一个线程。