Найти - Пользователи
Полная версия: Взаимодействие между потоками с помощью сигналов
Начало » Python для экспертов » Взаимодействие между потоками с помощью сигналов
1 2
DevNul_Pavel
Доброго времени суток! Обрисую вкратце проблему, есть PyQt-класс интерфейса,
внутри этого класса порождаются новые потоки
в которых выполняются определенные задачи, которые должны возвращать данные.
Так как работать с GUI из другого потока нельзя, то взаимодействие между потоками происходит
с помощью сигналов\слотов PyQT. При завершении работы в одном из подпотоков к родителю подключается слот,
эммитится сигнал и сразу же отключается (названия сигналов различные, так как подзадачки выполняют разные действия -
запросы к базе данных).

Данная система обмена сообщениями работает, проблем нет.

Но интересует какой-нибудь вариант, позволяющий организовать подобное взаимодействие между потоками на чистом питоне
(в других задачах также требуется выполнение обработки данных в главном потоке, а не вызов метода из дочернего потока для обработки)

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

Существует ли какие-нибудь аналоги PyQt сигналов\слотов на чистом питоне,
для оповещения главного потока, что необходимо выполнить определенный метод??

Например в Objective-C есть специальные методы performSelectorInBackground, вызываемый из главного потока и performSelectorInMainThread вызываемый в дочернем потоке при завершении работы задачи.
DevNul_Pavel
Тема вдоль и поперек уже изъезжена, но информацию по взаимодействию с помощью сообщений\сигналов найти не смог
Андрей Светлов
Проблема в том, что Qt event loop желает знать только о Qt объектах. Поэтому приходится опрашивать по таймеру. QApplication не имеет виртуальной функции onIdle (довольно распространенной в разных GUI) — остается только таймер.
DevNul_Pavel
Кажется нашел решение в стандртной библиотеке Python. Модуль concurrent.futures позволяет выполнить определенную функцию в фоновом потоке, организуя взимодействие с потоками на более высоком уровне.

with ThreadPoolExecutor(max_workers=1) as executor:
future = executor.submit(pow, 323, 1235)
print(future.result())

возврщемый объект future имеет метод add_done_callback(fn)

“Added callables are called in the order that they were added and are always called in a thread belonging to the process that added them.”
Если я правильно понял, то этот коллбек будет вызываться в том потоке, в котором его назначили (в моем случае в главном)

Пока возможности нету проверить
Андрей Светлов
Нет. В потоке-обработчике. Главный поток не имеет средств получить управление тогда, когда рабочий поток что-то посчитал.
DevNul_Pavel
Может знаете какие-нибудь сторонние python- библиотеки, способные организовать подобное взаимодействие между потоками с помощью сигналов, не таская за собой библиотеку pyqt? мне кажется довольно распространенный задача
DevNul_Pavel
Что-нибудь в духе организации очереди задач внутри объекта класса, если не ошибаюсь, так сделано в qt
Андрей Светлов
Проблема в интеграции этого стороннего кода с Qt event loop.
Qt активно такому сопротивляется.
Если же вам подходит приложение без Qt GUI — есть варианты.
DevNul_Pavel
Да, да, интересуют варианты без GUI. Случаем не работали с Celery, времени посмотреть не было детально, но вроде бы под эти цели создавалось.
Ed
multiprocesing.apply_async с колбэком - это часом не то, что вы ищете?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB