Qt C ++. Является ли stati c thread_local QNetworkAccessManager хорошим выбором для многопоточного приложения? - PullRequest
4 голосов
/ 12 июля 2020

Я использую многопоточное приложение, написанное на Qt (C ++).

Мне очень часто нужно делать запросы на получение / отправку из отдельных потоков.

Qt do c говорит:

Одного экземпляра QNetworkAccessManager должно хватить для всего приложения Qt. Поскольку QNetworkAccessManager основан на QObject, его можно использовать только из потока, которому он принадлежит.

Подходит ли static thread_local QNetworkAccessManager для моих целей?

1 Ответ

0 голосов
/ 12 июля 2020

Нет, не лучший выбор.

Вы не должны создавать экземпляры подклассов stati c или глобальных QObject, потому что обычно вам нужно, чтобы они были созданы после Qt объект приложения был создан (многое в Qt зависит от уже существующего объекта приложения). C ++ на самом деле не обеспечивает очень хорошего контроля над фактическим созданием объектов stati c, и здесь вы хотите иметь этот контроль.

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

Для их правильного уничтожения, когда у них нет естественный родитель (потому что родитель должен жить в одном потоке!), подключите сигнал его потока QThread::finished к слоту объектов QObject::deleteLater, и они будут полностью удалены, когда резьба заканчивается.

Если вам нужна простая функция, которая использует экземпляр QNAM текущего потока, вы можете иметь локальную для потока stati c указатель . Что-то вроде

static thread_local *thread_qnam;

void myfunc() {
    if (!thread_qnam) {
        thread_qnam = new QNetworkAccessManager;
        connect(QThread::currentThread, &QThread::finished(), thread_qnam, &QObject::deleteLater);
        // Whatever other setup you need.
        // It'd probably be good idea to wrap this in a function.
    }
    // Use thread_qnam...
}
...