微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Discord bot python - RuntimeError 无法启动新线程

如何解决Discord bot python - RuntimeError 无法启动新线程

我正在用 Python 3 开发一个 discord 机器人,但无法正常运行。我在 1&1 服务器上托管机器人,使用 nohup python3 main.py & 启动它。机器人运行并完美运行了一段时间然后崩溃,每次都有以 RuntimeError: can't start new thread. 结尾的大量错误回溯。此外,我的代码错误的源代码行每次都不相同。它总是来自 await [...] 行。

我在 Internet 上搜索了一段时间,但其他开发人员使用 import threading 和相关函数而我没有,我只使用 async / await 关键字。这是一个错误吗?我确定我没有达到线程限制,我一直在和几个朋友一起测试我的机器人,所以一次最多 3 到 4 个请求。机器人使用异步方法仅用于在 discord 上发送消息或反应,在任何地方都没有递归。

这是我拥有的多个 Traceback 之一。希望有人能帮助我,谢谢!

`

Ignoring exception in on_message
Traceback (most recent call last):
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/client.py",line 333,in _run_event
    await coro(*args,**kwargs)
  File "main.py",line 261,in on_message
    await message.channel.send(lines + "```")
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/abc.py",line 905,in send
    nonce=nonce,allowed_mentions=allowed_mentions)
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/discord/http.py",line 185,in request    async with self.__session.request(method,url,**kwargs) as r:
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/client.py",line 1012,in __aenter__
    self._resp = await self._coro
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/client.py",line 483,in _request
    timeout=real_timeout
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py",line 523,in connect
    proto = await self._create_connection(req,traces,timeout)
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py",line 859,in _create_connection
    req,line 967,in _create_direct_connection
    traces=traces),loop=self._loop)
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/connector.py",line 830,in _resolve_host
    self._resolver.resolve(host,port,family=self._family)
  File "/kunden/homepages/44/d758963141/htdocs/.local/lib/python3.7/site-packages/aiohttp/resolver.py",line 30,in resolve
    host,type=socket.soCK_STREAM,family=family)
  File "/usr/lib/python3.7/asyncio/base_events.py",line 789,in getaddrinfo
    None,getaddr_func,host,family,type,proto,flags)
  File "/usr/lib/python3.7/asyncio/base_events.py",line 752,in run_in_executor
    executor.submit(func,*args),loop=self)
  File "/usr/lib/python3.7/concurrent/futures/thread.py",line 160,in submit
    self._adjust_thread_count()
  File "/usr/lib/python3.7/concurrent/futures/thread.py",line 181,in _adjust_thread_count
    t.start()
  File "/usr/lib/python3.7/threading.py",line 847,in start
    _start_new_thread(self._bootstrap,())
RuntimeError: can't start new thread

`

====== 编辑 ======

这是我的代码示例:

`

@client.event
async def on_message(message) :
    global messagesId
    # ===== Block self messages =====
    if message.author == client.user :
        return
    # ===== $register =====
    elif message.content == "$register" :
        if not(await isRegistered(message.author.id,message.channel)) :
            try :
                refreshDb()
                sql = "INSERT INTO player VALUES (%s,%s,0)"
                dbCurs.execute(sql,(message.author.id,message.author.name))
                sql = "INSERT INTO schedule(player_id) VALUES (%s)"
                dbCurs.execute(sql,(message.author.id))
                db.commit()
            except Exception as e :
                await message.channel.send("Erreur interne #9")
                raise e
            await message.channel.send("Tu as été enregistré.")
        else :
            await message.channel.send("Tu es déjà enregistré.")
# ===== $schedule =====
elif message.content == "$schedule" :
    # Get player's current schedule
    data = None
    try :
        if await isRegistered(message.author.id,message.channel) :
            try :
                refreshDb()
                sql = "SELECT * FROM schedule WHERE player_id = %s"
                dbCurs.execute(sql,(message.author.id))
                data = dbCurs.fetchall()[0]
            except Exception as e :
                await message.channel.send("Erreur interne #4")
                raise e
        else :
            await message.channel.send("Tu dois t'enregistrer pour utiliser cette commande.")
            return
    except Exception as e :
        await message.channel.send("Erreur interne #5")
        raise e
    # Create lines
    text = "<@{}>\n{}".format(message.author.id,getScheduleText(data,1))
    sentMessage = await message.channel.send(text)
    # register message's id
    messagesId[sentMessage.id] = message.author.id
    # Add reactions
    i = 0
    keys = list(cols.keys())
    for key in keys :
        await sentMessage.add_reaction(bytes.decode(numbers[i]))
        i += 1
    # Register every messages id and delete everyone after 60 sec
    await deleteSched(sentMessage)

`

解决方法

您的代码显然使用线程,通过线程池执行器;这旨在运行持久任务,但让主 asyncio 线程可用于处理更多事件。当您的代码遇到某个 await 条件时,总是会在执行程序中创建新线程,因为这是事件循环可以自由工作的唯一时间。

所以...,您在执行程序中运行的任务似乎并未结束,而且您最终会遇到很多过时的线程。没有看到代码,我想我们不能说更多。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。