Поточная обработка в приложении PyQt: Использовать спокойные потоки или потоки Python?

Я не могу предложить вход на Стопке BI MS, но в новом Barcamp Orlando , люди от Pentaho были там и говорили об их продуктах, и это была чрезвычайно впечатляющая демонстрация.

то, что это - проект С открытым исходным кодом, который можно расширить сами, а также заплаченный пакет для действительно хорошего сервиса, оставляет Вас с большим количеством опций. Они продемонстрировали некоторую заплаченную работу, которую они сделали для клиента и их определенно wow'd толпа.

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

Поэтому, насколько компания идет, Pentaho действительно произвел на меня впечатление и их работой и насколько дружественный и доступный все их разработчики были.

107
задан Community 23 May 2017 в 12:09
поделиться

7 ответов

Это обсуждалось не так давно в списке рассылки PyQt. Цитируя Джованни Баджо комментарии по этому поводу:

В основном это то же самое. Основное отличие в том, что QThreads лучше интегрирован с Qt (асинхронные сигналы / слоты, цикл событий и т. д.). Кроме того, вы не можете использовать Qt из потока Python (например, вы не можете отправить событие в основной поток через QApplication.postEvent): вы для этого нужен QThread.

Общее практическое правило может заключаться в использовании QThreads, если вы собираетесь каким-то образом взаимодействовать с Qt, и в противном случае использовать потоки Python.

И некоторые более ранние комментарии по этому вопросу из PyQt's автор: «они обе являются оболочками для одной и той же реализации нативного потока». И обе реализации используют GIL одинаково.

101
ответ дан 24 November 2019 в 03:41
поделиться

Преимущество QThread в том, что он интегрирован с остальной частью библиотеки Qt. То есть, методы, поддерживающие потоки в Qt, должны будут знать, в каком потоке они работают, а для перемещения объектов между потоками вам нужно будет использовать QThread . Еще одна полезная функция - запуск собственного цикла событий в потоке.

Если вы обращаетесь к HTTP-серверу, вам следует рассмотреть QNetworkAccessManager .

21
ответ дан 24 November 2019 в 03:41
поделиться

Потоки Python будут проще и безопаснее, и, поскольку они предназначены для приложений на основе ввода-вывода, они могут обходить GIL. Тем не менее, рассматривали ли вы неблокирующий ввод-вывод с использованием Twisted или неблокирующих сокетов / select?

РЕДАКТИРОВАТЬ: подробнее о потоках

Потоки Python

Потоки Python являются системными потоками. Однако Python использует глобальную блокировку интерпретатора (GIL), чтобы гарантировать, что интерпретатор одновременно выполняет только блок инструкций байтового кода определенного размера. К счастью, Python выпускает GIL во время операций ввода / вывода, что делает потоки полезными для моделирования неблокирующего ввода / вывода.

Важное предостережение: Это может вводить в заблуждение, так как количество инструкций байтового кода делает not соответствует количеству строк в программе. Даже одно присвоение не может быть атомарным в Python, поэтому блокировка мьютекса необходима для любого блока кода, который должен выполняться атомарно, даже с GIL.

Потоки QT

Когда Python передает управление стороннему скомпилированному модулю, он освобождает ГИЛ. Ответственность за обеспечение атомарности там, где это необходимо, ложится на модуль. Когда управление будет передано обратно, Python будет использовать GIL. Это может сбивать с толку использование сторонних библиотек в сочетании с потоками. Еще сложнее использовать внешнюю библиотеку потоков, потому что это добавляет неопределенности относительно того, где и когда управление находится в руках модуля, а не интерпретатора.

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

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

Неблокирующий ввод-вывод

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

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

Одно хорошее решение для событийно-ориентированного , неблокирующий ввод-вывод - это новая библиотека Diesel . На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

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

Одно хорошее решение для событийно-ориентированного , неблокирующий ввод-вывод - это новая библиотека Diesel . На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

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

Одно хорошее решение для событийно-ориентированного , неблокирующий ввод-вывод - это новая библиотека Diesel . На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

например, что делать, когда код, зависящий от одного открытого канала, дополнительно зависит от результатов кода, который будет вызываться, когда другой открытый канал возвращает данные.

Одним из хороших решений для событийно-неблокирующего ввода-вывода является новый Diesel библиотека. На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

например, что делать, когда код, зависящий от одного открытого канала, дополнительно зависит от результатов кода, который будет вызываться, когда другой открытый канал возвращает данные.

Одним из хороших решений для событийно-неблокирующего ввода-вывода является новый Diesel библиотека. На данный момент он ограничен Linux, но он необычайно быстр и довольно элегантен.

Также стоит потратить время на изучение pyevent , оболочки для замечательной библиотеки libevent, которая обеспечивает базовую структуру для программирования на основе событий с использованием самого быстрого метода, доступного для вашей системы (определяется во время компиляции).

32
ответ дан 24 November 2019 в 03:41
поделиться

У Джеффа есть хорошие моменты. Только один основной поток может выполнять любые обновления графического интерфейса. Если вам действительно нужно обновить графический интерфейс из потока, сигналы Qt-4 очереди подключения упрощают отправку данных по потокам и будут автоматически вызываться, если вы используете QThread; Я не уверен, будут ли они, если вы используете потоки Python, хотя добавить параметр в connect () несложно.

9
ответ дан 24 November 2019 в 03:41
поделиться

I asked myself the same question when I was working to PyTalk.

If you are using Qt, you need to use QThread to be able to use the Qt framework and expecially the signal/slot system.

With the signal/slot engine, you will be able to talk from a thread to another and with every part of your project.

Moreover, there is not very performance question about this choice since both are a C++ bindings.

Here is my experience of PyQt and thread.

I encourage you to use QThread.

13
ответ дан 24 November 2019 в 03:41
поделиться

Я не могу комментировать точные различия между потоками Python и PyQt, но я делал то, что вы пытаетесь сделать, используя QThread , QNetworkAcessManager и не забудьте вызвать QApplication.processEvents () , пока поток активен. Если скорость отклика графического интерфейса действительно является проблемой, которую вы пытаетесь решить, поможет более поздняя .

0
ответ дан 24 November 2019 в 03:41
поделиться

Я тоже не могу рекомендовать, но могу попытаться описать различия между потоками CPython и Qt.

Прежде всего, потоки CPython не выполняются одновременно, по крайней мере, не код Python. Да, они действительно создают системные потоки для каждого потока Python, однако разрешено запускать только поток, в настоящее время содержащий глобальную блокировку интерпретатора (расширения C и код FFI могут обходить его, но байт-код Python не выполняется, пока поток не содержит GIL).

С другой стороны, у нас есть потоки Qt, которые в основном являются общим слоем над системными потоками, не имеют глобальной блокировки интерпретатора и, следовательно, могут работать одновременно. Я не уверен, как PyQt с этим справляется, однако, если ваши потоки Qt не вызывают код Python,

5
ответ дан 24 November 2019 в 03:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: