Error: Access is denied
сообщает, что шаблон недоступен. Попробуйте открыть шаблон в своем браузере. Что-то вроде этого: http: //my_project/partials1/view3.html . Чтобы увидеть полный URL-адрес, используемый вашим приложением, используйте консоль dubug (вкладка XHR).
Требование, чтобы "someOperation is not reentrant"
было нечетным. Что должно произойти, если попытка возвращения? Учитывая, что someOperation
можно вызывать только из потока main
, я вижу только два варианта ...
1) Полностью заблокирует цикл событий потока, не позволяя корректно функционировать текущему диалоговому окну сообщений.
2) Разрешит одновременное ведение всех диалогов сообщений, а не их сериализацию.
Вместо того, чтобы пытаться сделать someOperation
не-реентерабельным, я думаю, вам нужно убедиться, что вы используете его так, чтобы не привести к реентерабельности.
Одним из вариантов может быть использование отдельного QObject
экземпляра производного класса самостоятельно QThread
. Рассмотрим следующее ...
class signal_serialiser: public QObject {
Q_OBJECT;
signals:
void signal1();
void signal2();
void signal3();
};
Если экземпляр signal_serialiser
перемещается в свой собственный поток, он может действовать как очередь для буферизации и пересылки различных сигналов, если используются подходящие типы соединений. В вашем коде у вас есть ...
QObject::connect(w, SIGNAL(signal1()), a, SLOT(slot1()), Qt::QueuedConnection);
QObject::connect(w, SIGNAL(signal2()), a, SLOT(slot2()), Qt::QueuedConnection);
QObject::connect(w, SIGNAL(signal3()), a, SLOT(slot3()), Qt::QueuedConnection);
Измените это на ...
signal_serialiser signal_serialiser;
QObject::connect(w, SIGNAL(signal1()), &signal_serialiser, SIGNAL(signal1()));
QObject::connect(w, SIGNAL(signal2()), &signal_serialiser, SIGNAL(signal2()));
QObject::connect(w, SIGNAL(signal3()), &signal_serialiser, SIGNAL(signal3()));
/*
* Note the use of Qt::BlockingQueuedConnection for the
* signal_serialiser --> A connections.
*/
QObject::connect(&signal_serialiser, SIGNAL(signal1()), a, SLOT(slot1()), Qt::BlockingQueuedConnection);
QObject::connect(&signal_serialiser, SIGNAL(signal2()), a, SLOT(slot2()), Qt::BlockingQueuedConnection);
QObject::connect(&signal_serialiser, SIGNAL(signal3()), a, SLOT(slot3()), Qt::BlockingQueuedConnection);
QThread signal_serialiser_thread;
signal_serialiser.moveToThread(&signal_serialiser_thread);
signal_serialiser_thread.start();
Я только провел базовое тестирование, но, похоже, оно дает желаемое поведение.
Это потому, что ваша функция void someOperation()
не является реентерабельной .
Статические функции QMessageBox
охватывают свой собственный цикл обработки событий, который неоднократно вызывает QCoreApplication::processEvents()
:
someOperation()
застревает в QMessageBox::warning(...)
. exec()
вызывает processEvents()
, 3. который видит второй сигнал someOperation()
mutex
не удалась. Как решить эту проблему, зависит от того, чего вы хотите достичь ...
О вашем общем подходе к QThread
: Вы делаете это неправильно.
(Эта ссылка дает хорошее начало в теме, но не является полным решением.)
Вы создаете и запускаете фоновый поток. Но этот поток только испустит три сигнала и затем закончится.
Слоты будут вызываться в основном цикле событий (GUI), потому что это сходство потоков вашего A *a
.
Чтобы слоты выполнялись в фоновом режиме, вам необходимо:
A *a = new A();
Worker *w = new Worker(&app);
(или ни с чем, по крайней мере, не с a
) a->moveToThread(Worker);
Worker::run()
или, если вы действительно хотите (см. пункт 5), вызовите базовую реализацию: QThread::run();