В настоящее время я ставлю FUSE вместе с qt5. между Qt и FUSE нет моста, и основной поток FUSE (который порождает другие рабочие потоки FUSE) и QCoreApplication просто работают бок о бок.
но я хочу иметь возможность отправлять и получать данные между объектом, основанным на QObject, и функцией чтения (..) pthread, показанной в [0], с использованием SIGNALS и SLOTS в Qt.
Теперь я хочу изменить функцию Read (..) из [0] для получения данных, используя SIGNALS и SLOTS в Qt из класса, основанного на QObject. отправка сигнала из pthread работает, но без явного QEventLoop я не могу получить ответ. поэтому я искал код из [1], который превосходен по дизайну, но я пока не получил его работу.
псевдокод (взят из [1]):
QNetworkAccessManager qnam;
QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));
QEventLoop loop;
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
loop.exec();
/* reply has finished, use it */
выглядит интересно, все, что мне нужно, это производный класс QObject, похожий на QNetworkReply, который будет обрабатывать запрос.
когда я играл с этим кодом, у меня возникла проблема, заключающаяся в том, что моя реализация QNetworkReply не дожидалась запуска loop.exec (), и тогда SIGNAL готового () сигнала не был бы получен циклом.
но разве нет ничего проще, чем создать QEventLoop?
НОТА: QNetworkReply и QNetworkAccessManager в примере из [1] создаются внутри pthread, однако мне необходимо иметь возможность связываться с четной очередью QCoreApplication, используя SIGNALS и SLOTS, поскольку объект с данными в нем поступает из другого QThread (в это либо QCoreApplication, либо специальный QThread).
я также нашел [2] и возможно:
connect (src, SIGNAL (сигнал-подпись), dest, SLOT (слот-подпись), Qt :: QueuedConnection);
это все, что я хочу, но я сомневаюсь в этом.
То, что вы, вероятно, сталкиваетесь с тем, что QNetworkAccessManager
внутренне использует потоки для обработки http-запросов. Вот почему это «не ждет» вас. Для ее исправления требуется довольно простая модификация:
QNetworkAccessManager qnam;
QEventLoop loop;
QNetworkReply *reply = qnam.get(QNetworkRequest(QUrl(...)));
QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
if (!reply->isFinished()) loop.exec();
Когда объект, являющийся источником сигнала, живет (создается в) в потоке, отличном от потока объекта со слотами, соединение будет QueuedConnection
введите автоматически.
Настоящая проблема: каждый QObject
имеет сродство потока. Сходство по умолчанию — это поток, в котором был создан объект. Вы не должны использовать такие объекты непосредственно из других потоков.
Скорее всего, вы создаете экземпляры объектов отправителя и получателя в одном потоке, но затем излучаете сигнал из другого потока. Это источник ошибок потенциальных ошибок и приводит к неопределенному поведению, если пользователь таким объектом является принудительное неавтоматическое прямое соединение.
Всякий раз, когда вы делаете emit object->signal(...)
должен иметь место следующий инвариант:
Q_ASSERT(QThread::currentThread() == object->thread());
Не стесняйтесь добавлять эти инвариантные проверки перед каждым emit()
что вы явно выполняете.
Если утверждение не удалось, вам нужно использовать QObject::moveToThread
переместить объект в поток, где вы хотите запустить его сигналы. Вы можете получить QThread
для данного pthread
позвонив QThread::currentThread()
из кода, который работает в pthread
, Экземпляр QThread
будет создан автоматически для вас 🙂
Да, вам нужен метод Qt :: QueuedConnection. Но также убедитесь, что вы используете многопоточную библиотеку Qt. IIRC это вариант времени сборки.
Смотрите также: Документация Qt