#python #python-3.x #multiprocessing #discord.py #pool
Вопрос:
Я создал бота discord, который использует многопроцессорную обработку (я впервые использую многопроцессорную обработку) для повышения эффективности. Бот и без того прекрасно работает, мне просто было скучно, и я хотел его улучшить. Этот бот предназначен для школьного сервера discord, который просто получает обед в течение дня, используя свой api (интересно, почему он у них есть).
По какой-то причине моя многопроцессорная обработка заставляет мой код выполняться 5 раз и каким-то образом заставляет моего бота discord отправлять в 5 раз больше сообщений, чем следовало бы. Честно говоря, я понятия не имею, что с этим происходит. Я запускаю эту функцию перед тем, как что-либо сделать с моим ботом, и каким-то образом она заставляет 5 ботов работать одновременно с одним и тем же токеном. Требуется около 30 секунд, чтобы все 5 ботов вышли в Сеть, что они и делают один за другим. Еще одна незначительная вещь заключается в том, что многопроцессорная обработка печатает «нет» 5 раз без причины каждый раз, когда вызывается функция.
Спасибо вам за то, что нашли время подготовить мою нить!
from asyncio.tasks import create_task
import discord
from discord.ext.commands import Bot
import datetime, asyncio
from discord.message import Message
import schedule
import random
import requests
import json
import datetime
import multiprocessing
from multiprocessing import Pool
def get_lunch(day): # Sorting thru a json that is scraped, not gonna put it here b/c i don't want to dox myself, and it works perfectly
all_todos = load_pre_reqs()
gotten_lunch = (str(all_todos.split("menu_items")[2 day].split(r'"name"')[1].split(",")[0]))
formated_lunch = (gotten_lunch[3:int(len(gotten_lunch)) -1 ])
return(formated_lunch)
# if anyone is trying to run this code u can use something like instead of above
# def get_lunch(day):
# lunches = ["a", "b", "c", "d", "e"]
# return lunches[day]
def lunch():
if __name__ == '__main__':
p = Pool(5)
week = p.map(get_lunch, range(5))
return week
# I run this^ on it's own and works well, but causes the rest of the code to repeat 5x
print(lunch())
bot = Bot(command_prefix='!')
client = discord.Client()
loop = asyncio.get_event_loop() # here for future
TOKEN = 'insert token here'
@client.event
async def on_ready():
print(f"connected as {client.user}")
@client.event
async def on_message(message):
if message.author == client.user:
return
else:
await message.channel.send("hi") #just here to make sure bot is running
client.run(TOKEN)
Ответ №1:
Документация в multiprocessing
модуле достаточно ясно говорит об этом. Когда вы запускаете модуль с многопроцессорной обработкой, он запускает совершенно новый процесс с совершенно новым интерпретатором, который должен импортировать ваш основной модуль и все необходимые ему модули. Если у вас нет вашего одноразового кода в if __name__=='__main__':
блоке, как это предлагается в документации, то он будет повторно запускаться в каждом процессе, который запускается.
Вот почему вы должны привыкнуть помещать основной код вашего приложения в def main():
и делать
if __name__ == '__main__':
main()
Импорт, запущенный с помощью многопроцессорной обработки, не будет __name__
настроен таким образом.
Комментарии:
1. Спасибо за ответ, но я не совсем понимаю. Вы хотите сказать, что я должен поместить весь свой код в main()? Или я ставлю только некоторые, и если да, то какой код и как я буду вызывать функции теперь, когда они вложены?
2. Любой код, который должен быть выполнен только один раз, должен быть в основном. Вторичные процессы не будут запущены
main
.