Итак, такая вот загогулина:
Вспомогательный поток (CalibrateThread):
void CalibrateThread::setCommand(const QString commandStr, const int pause)
{
command = commandStr;
this->pause = pause;
/*DEBUG*/log("setCommand(): at exit(0);");
exit(0);
/*DEBUG*/log("setCommand(): after exit(0);");
}
...
void CalibrateThread::run()
{
forever {
/*DEBUG*/log("run(): forever {...}: at emit readyToGetCommand();");
emit readyToGetCommand();
/*DEBUG*/log("run(): forever {...}: at exec();");
exec();
/*DEBUG*/log("run(): forever {...}: after exec();");
}
}
Главний поток (MainWindow):
calibrator = new CalibrateThread;
...
connect(calibrator, SIGNAL(readyToGetCommand()), this, SLOT(runNextTest()));
connect(thid, SIGNAL(commandToSet(const QString, const int)), calibrator, SLOT(setCommand(const QString, const int)));
...
void MainWindow::runNextTest()
{
...
/*DEBUG*/log("runNexTest(): at emit commandToSet(command, pause);");
emit commandToSet(command, pause);
}
Так вот, при работе программы происходит следующее:
Вариант 1 - если поток calibrator запускается с приоритетом выше чем главный
Все работает как "хочется", то есть: Калибратор посылает главному потоку сигнал readyToGetCommand, что готов принять команду и запускает еxec(), то есть ждет сигнала от главного с командой. Далее главный получает сигнал от калибратора и отвечает ему сигналом с командой, который приводит к запуску слота калибратора setCommand(...) в котором и запускается exit(0), что и приводит к выходу из exec() в калибраторе.
Вариант 2 - если поток calibrator запускается с приоритетом меньше чем главный
Програма зависает... Она не может выйти с exec() в калибраторе, так как всю свою работу (получение сигнала и отправка ответного с вызовом слота setCommand()) главный успел сделать еще до exec() в калибраторе.
Итак вопрос: почему так происходит? Ведь при конекшене сигнала commandToSet() cо слотом setCommand() используется AutoConnection что в даном случае равно QueuedConnection, а это ведь должно значить, что слот выполнится не сразу, а когда ивент луп ему даст это сделать, то есть тогда когда запустится exec()... А выходит что слот запускается еще до этого...
Это видно по крайней мере из того что пишется в логе, то есть что то типа такого:
run(): forever {...}: at emit readyToGetCommand();
runNexTest(): at emit commandToSet(command, pause);
setCommand(): at exit(0);
setCommand(): after exit(0);
run(): forever {...}: at exec();КОНЕЦ:) то есть тут программа и начинает висеть.
Вообще то есть еще и второй прикол, а именно в том, что когда при ВАРИАНТЕ 1 все работает то лог выглядит так:
run(): forever {...}: at emit readyToGetCommand();
runNexTest(): at emit commandToSet(command, pause);
setCommand(): at exit(0);
setCommand(): after exit(0);
run(): forever {...}: at exec();
run(): forever {...}: after exec();тоесть программа не виснит, выходит из екзека, !но почему то лог не выглядит хотя бы вот так:
run(): forever {...}: at emit readyToGetCommand();
runNexTest(): at emit commandToSet(command, pause);
run(): forever {...}: at exec();
setCommand(): at exit(0);
setCommand(): after exit(0);
run(): forever {...}: after exec();Но второй вопрос это такое... Просто может эта проблема завязана на том как у меня реализована запись в лог, и в какой последовательности будут обрабатываться мои ивенты записи в лог...
Сейчас главное, на что я хочу получить ответ - это почему "не работает" queuedconnection, и если действительно это не моя ошибка, а это так и должно быть, то как тогда мне реализовать такую комуникацию чтобы все работало...