Ответы пользователя по тегу Многопоточность
  • Почему возникает ошибка cannot pickle '_thread.lock' object?

    Vindicar
    @Vindicar
    pickle используется для проброса данных между процессами, и оно умеет сериализовывать только примитивы и простые коллекции. Какое-то из передаваемых тобой значений в parameters не подпадает под это определение.
    Я подозреваю что это self.client, но это уже тебе надо проверять.
    Ещё раз: в другой процесс можно передавать числа, строки, логические значения, кортежи, списки, словари. Всё остальное - без гарантий.
    Ответ написан
  • Реализация многопоточности в vk bot?

    Vindicar
    @Vindicar
    Ну для начала, что должен делать этот новый поток?
    Оформи его действия отдельной функцией, и её и задавай.
    Другой вопрос, ты уверен что тебе нужны потоки для этого? И уверен ли ты, что с vk-api можно работать из нескольких потоков?
    Ответ написан
  • Как запустить поток через время?

    Vindicar
    @Vindicar
    Запустить поток сразу, но в потоке первым делом уснуть на заданное время?
    Объект timedelta имеет метод totalseconds(), который даст длительность интервала в секундах, как раз как это требуется time.sleep().
    Для небольших интервалов (в пределах минут) сойдёт.
    Ответ написан
  • Как из дочернего процесса вытащить данные?

    Vindicar
    @Vindicar
    Попробуй использовать Pool.map().
    Пример его использования буквально в самом начале официальной документации.
    Ответ написан
    2 комментария
  • Добавление аргументов к функции с threading?

    Vindicar
    @Vindicar
    1. На момент вызова конструктора Thread переменная conn ещё не существует. Тебе нужно создавать поток тогда, когда она уже получила значение.
    2. Не вызывай метод run(). Он будет вызван сам, в отдельном потоке. Для запуска этого потока нужно вызвать start(). И имей ввиду, что у тебя send() отрабатывает однажды, и останавливается.

    Я бы посоветовал попрактиковаться в работе с потоками, для начала.
    Ответ написан
    Комментировать
  • Почему - то когда работаю с классом не через главный поток, переменные в классе не изменяются, почему?

    Vindicar
    @Vindicar
    Ну второе как раз объяснимо, ты запускаешь work() для одного и того же класса.
    Пока первая копия work() спит в time.sleep(1), начинает выполняться вторая, так как всё происходит в отдельных потоках. Вторая видит isworking = 1, и останавливается.
    Ответ написан
    2 комментария
  • Как запустить одновременно два потока Python?

    Vindicar
    @Vindicar
    В CPython есть проблема - в один момент времени исполняется всегда один поток, даже если ядер у проца несколько. Так что "одновременно" на питоне запустить два потока проблематично. Они будут чередоваться, исполняясь по кусочкам. Исключение - если поток ждёт завершения операции ввода-вывода, или чего-то подобного, т.е. не исполняет непосредственно код на питоне. Тогда он не блокирует другие потоки.

    При этом нет никаких гарантий насчёт порядка их исполнения. Когда ОС решит переключиться с одного потока на другой - ты не контролируешь. У меня, например, твой первый код тоже выводит "hellohello".

    Так что да, твой код выполняется настолько "одновременно", насколько это возможно.
    Ответ написан
  • Как использовать asyncio внутри Thread Python?

    Vindicar
    @Vindicar
    Во-первых, несколько асинхронных задач прекрасно уживаются друг с другом. На кой тебе вообще нужны потоки для этого? Чем не устроил loop.create_task(), или asyncio.gather()?

    Во-вторых, куда проще завернуть долгий синхронный код в поток, а уже поток - в асинхронную задачу, чем наоборот. Подумай над этим.

    В-третьих, технически ты можешь создавать свой цикл реактора (asyncio loop) в каждом потоке. Почитай доки на asyncio как это делается. Но нужно помнить, что async-объекты из разных реакторов не дружат друг с другом. Так что подчеркиваю красным: не надо это делать. Лучше сначала попробуй по-иному подойти к проблеме.
    Ответ написан
    4 комментария
  • RuntimeError: There is no current event loop in thread 'Thread-2'. Что делать?

    Vindicar
    @Vindicar
    Мешать многопоточность с асинхронностью - плохая идея. Зачем тебе это потребовалось?
    Если нужно выполнить длительную синхронную задачу в отдельном потоке, используй loop.run_in_executor() - он позволяет аккуратно представить выполнение потока как обычную асинхронную задачу.
    Ответ написан
    Комментировать
  • Как результат каждого процесса записать в отдельный соответствующий файл (Multiprocessing, Python)?

    Vindicar
    @Vindicar
    for i,item in enumerate(data_group):
        file_name = f"{i}.txt"
        #ну и далее по тексту

    Как-то так? Я серьёзно не вижу в чём затруднение.
    Ответ написан
    Комментировать
  • Как настроить блокировку только для некоторых потоков?

    Vindicar
    @Vindicar
    Lock (он же мьютекс) такими вещами не занимается.
    Ты можешь скостылить конструкцию, при которой у каждого order есть свой Lock, но это будет или расточительно (если всегда создавать Lock) или утомительно (если создавать его при обращении к order).
    Асинхронный подход может помочь, но он потребует почти полной переделки кода. Не очень-то удобно.
    А вообще стоит задаться вопросом - этот Lock точно является узким местом?
    Ответ написан
    Комментировать
  • Что предпочтительнее - многопоточность или параллелизм (Python)?

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

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

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

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

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

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

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

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

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

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

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

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

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

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