简体   繁体   中英

RuntimeError when multithreading python "RuntimeError: There is no current event loop in thread 'Thread-1'."

I am trying to run multiple discord bots with the same script at once. The way I am doing this is going down a csv file, to get the bot token and bot name. I then start my script:

import time, csv, re, random, string, sys, os, asyncio
from datetime import datetime
from threading import Thread
import discord
from dotenv import load_dotenv
from discord_webhook import DiscordWebhook, DiscordEmbed

def main(bottoken, botname):
    TOKEN = (bottoken)
    client = discord.Client()

    @client.event
    async def on_ready():
        print(f'{client.user.name} has connected to Discord!')

    @client.event
    async def on_message(message):
         #do stuff
         print('Do stuff')

    client.run(TOKEN)

def runtask():

    if __name__ == '__main__':
        with open('botinfo.csv', 'r') as f:
            reader = csv.reader(f, delimiter=',')
            for i, row in enumerate(reader):
                Thread(target = main, args=(row[0], row[1])).start()

if __name__ == '__main__':
    runtask()

But then I get this error:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/alexforman/Documents/GitHub/bot-price-monitor/frontend_multithread.py", line 14, in main
    client = discord.Client()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/discord/client.py", line 216, in __init__
    self.loop = asyncio.get_event_loop() if loop is None else loop
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-1'.

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/alexforman/Documents/GitHub/bot-price-monitor/frontend_multithread.py", line 14, in main
    client = discord.Client()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/discord/client.py", line 216, in __init__
    self.loop = asyncio.get_event_loop() if loop is None else loop
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/events.py", line 644, in get_event_loop
    % threading.current_thread().name)
RuntimeError: There is no current event loop in thread 'Thread-2'.

Does anyone have any ideas on how I could fix it?

You don't need to start a separate thread for each bot, the asyncio event loop is perfectly capable of serving all bots at once. (That's the kind of thing event loops are designed for.)

You just need to start all the bots as coroutines of the same asyncio event loop:

async def run_client(bottoken, botname):
    TOKEN = (bottoken)
    client = discord.Client()

    @client.event
    async def on_ready():
        print(f'{client.user.name} has connected to Discord!')

    @client.event
    async def on_message(message):
         #do stuff
         print('Do stuff')

    # can't use client.run() because it would block the event loop
    # but we can use client.start(), which is a coroutine that does
    # the same thing (and which is internally called by client.run)
    await client.start(TOKEN)

async def main():
    coros = []
    with open('botinfo.csv', 'r') as f:
        reader = csv.reader(f, delimiter=',')
        for i, row in enumerate(reader):
            coros.append(run_client(row[0], row[1]))
    await asyncio.gather(*coros)

if __name__ == '__main__':
    asyncio.run(main())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM