Ответы пользователя по тегу Многопоточность
  • Что предпочтительнее - многопоточность или параллелизм (Python)?

    Vindicar
    @Vindicar
    RTFM!
    asyncio имеет удобный механизм асинхронного запуска задачи в отдельном процессе через run_in_executor(), так что это не такой уж жесткий выбор.

    Многопроцессность быстрее, но есть проблемы с передачей сложный объектов. По сути, можно отдавать туда и обратно только примитивы, словари и списки. Вещи типа массивов numpy приходится конвертировать.
    Так что если это не проблема - multiprocessing рулит.
    Ответ написан
    Комментировать
  • Как разобраться с многопотоками в пайтоне?

    Vindicar
    @Vindicar
    RTFM!
    btn2=tk.Button(frame, text="start AutoClicker", bg="white", padx="50", pady="10")

    А почему тут должно что-то происходить? Я не вижу в твоем коде назначения обработчика щелчку по этой кнопке.
    Ответ написан
    5 комментариев
  • Неправильное поведение Thread с target=lambda?

    Vindicar
    @Vindicar
    RTFM!
    У тебя в первом случае тело потока (лямбда) захватывает через замыкание не значение i, а ссылку на i.
    К моменту старта в первом случае i будет иметь другое значение.
    Вот почему нужно использовать args - как во-втором случае. Тогда происходит захват значения - не через замыкание, а через параметр.
    Ответ написан
    4 комментария
  • Не работает многопоточность?

    Vindicar
    @Vindicar
    RTFM!
    Thread(target=egz_checkden(), args=())

    Когда уже погромисты научатся различать результат вызова функции (со скобками) и ссылку на функцию (без скобок).
    У тебя сейчас Питон пытается выполнить egz_checkden(), чтобы получить её возвращаемое значение и использовать его в качестве target.

    И да, у тебя в egz_checkden() бесконечная рекурсия, пусть и медленная. Вылетит с переполнением стека, хотя и не сразу. Не делай так, используй нормальный цикл.
    Ответ написан
    4 комментария
  • Как использовать multiprocessing в tkinter?

    Vindicar
    @Vindicar
    RTFM!
    Исходи из того, что между процессами лучше передавать только примитивные типы данных и простые коллекции (списки, кортежи, словари). Так что не надо передавать объекты Tkinter как есть, извлеки из них требуемые данные и передавай их.
    EDIT:
    Идеальный сценарий - использование пары multiprocessing.Queue.
    Код дочернего процесса слушает одну очередь, и обрабатывает полученные там задания, а потом пишет в другую ответы.
    Код материнского процесса занимается работой с GUI, складывает задания в первую очередь, и время от времени мониторит вторую очередь на предмет новых ответов. Используй root.after() для мониторинга.
    Ответ написан
  • Как вызвать self класса родителя?

    Vindicar
    @Vindicar
    RTFM!
    Неправильная терминология. Example - не родитель MyThread.
    Передайте ссылку на экземпляр Example (или на нужное поле) через параметр конструктора MyThread и сохраните её как экземплярную переменную класса MyThread. Но имейте ввиду - не факт, что вы сможете обратиться к элементам управления QT непосредственно из другого потока.
    Ответ написан
  • Как правильно настроить многопоточность у бота telegram?

    Vindicar
    @Vindicar
    RTFM!
    Если коротко: пусть бот работает в главном потоке. ФЗ, синхронно или асинхронно, зависит от используемой библиотеки. Судя по приведённому коду, синхронно.
    А вот все длительные операции запускайте в отдельных потоках или даже процессах.
    Для общения между потоком бота и рабочими потоками/процессами организуйте две очереди. Из одной потоки обработки данных будут принимать задания. В другую они будут складывать сообщения для отправки (текст + id пользователя, например). Тогда основной бот должен по готовности запроса положить объект с описанием задания в первую очередь, а также периодически проверять наличие сообщений во второй. При наличии - извлекать и отправлять по назначению.
    Ответ написан
  • Как исправить бота с несколькими потоками?

    Vindicar
    @Vindicar
    RTFM!
    Я бы посоветовал использовать asyncio.Queue, но там есть тонкости при работе с несколькими потоками.
    Пусть поток-парсер вообще не занимается вопросами работы с ботом, а просто периодически производит парсинг, и если есть новости - кладёт их описание в выходную очередь. Он должен делать это с помощью call_soon_threadsafe(), как описано тут, так как класс asyncio.Queue не является потокобезопасным.
    Зато бот в главном потоке может просто в цикле await'ить метод get() очереди, и отправлять сообщения по получению очередного объекта.

    Альтернатива - использовать классический потокобезопасный queue.
    Так будет проще помещать в него результаты парсинга, но сложнее их извлекать - придётся периодически (типа раз в 1-5 секунд) вызывать метод get_nowait(), чтобы узнать, есть ли что-то в очереди. Блокирующий get() подвесит бота.
    Ответ написан
    3 комментария
  • Как правильно запустить Discord-бота в потоке?

    Vindicar
    @Vindicar
    RTFM!
    Я не в курсе как работает threadSignal.connect(), но я знаю, что bot.run() не вернёт управление, пока бот не завершит работу.
    Т.е. из функции BOT_RUN поток управления не вернётся ещё очень долго.
    Возможно, стоит перепланировать, какой поток что делает? Выделить отдельный поток под bot.run()?
    Ответ написан
    Комментировать
  • Почему сначала заканчивается func1, а уж потом выводит, что func1 началась?

    Vindicar
    @Vindicar
    RTFM!
    t = threading.Thread (target = func1())
    Ты запускаешь поток, в качестве тела которого указываешь то, что вернула после вызова func1.
    Это None, и поток ничего не делает.
    Исправь на
    t = threading.Thread (target = func1)
    Нужно запомнить разницу:
    func1 - ссылка на функцию
    func1() - результат вызова функции без параметров
    Ответ написан
    Комментировать
  • Как лучше сделать функцию прибавления +30 в бд, так чтобы при 2 пользователях не вис код, и не ждал окончания цикла?

    Vindicar
    @Vindicar
    RTFM!
    Учи, как работает асинхронное программирование.
    Если на пальцах: всякий раз, когда ты делаешь await чтототам, выполнение асинхронной функции (вроде обработчика события) приостанавливается, и передаётся другой.
    А вот код в промежутке между await вызовами (ну или началом-концом функции) выполняется непрерывно, и занимает поток управления. Пока этот код выполняется, остальной бот стоит!
    Теперь посмотри что у тебя:
    while (True):
                user.balance += user.s9 * 30
                time.sleep(30)
                user.save()

    time.sleep() понятия не имеет про асинхронность, и не отдаёт управление другим асинхронным функциям. Поэтому пока она выполняется, остальной бот стоит.
    Да, даже для одного пользователя.

    Как минимум, нужно исправить две вещи.
    1. используй await asyncio.sleep() вместо time.sleep(). asyncio.sleep() знает про асинхронность, и приостановит функцию с передачей управления, т.е. бот сможет делать что-то ещё пока эта функция ждёт.
    2. while (True) - это не тру. Предусмотри код выхода из цикла! Или по максимальному числу итераций, или по команде, или по смене статуса пользователя... или по всему вышеперечисленному.
    Ответ написан
    Комментировать