Cześć,
Utworzyłem aplikację konsolową, która w pliku main.cpp ma następujący kod:
#include <QCoreApplication>
#include <QThread>
#include <QObject>
class file_logger : public QObject
{
Q_OBJECT
public slots:
void save_log()
{
printf("thread before sleep\n");
QThread::sleep(3);
printf("thread after sleep\n");
printf("save_log\n");
}
};
class io_thread : public QThread
{
Q_OBJECT
public:
~io_thread()
{
printf("thread before quit\n");
quit();
printf("thread after quit\n");
printf("thread before wait\n");
wait();
printf("thread after wait\n");
}
file_logger * file_log;
signals:
void init_finished();
protected:
void run()
{
file_log = new file_logger();
emit init_finished();
exec();
//QCoreApplication::processEvents();
delete file_log;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
io_thread thread;
QEventLoop loop;
QObject::connect(&thread, &io_thread::init_finished, &loop, &QEventLoop::quit, Qt::QueuedConnection);
thread.start();
loop.exec();
printf("invoke 1\n");
QMetaObject::invokeMethod(thread.file_log, "save_log", Qt::QueuedConnection);
printf("invoke 2\n");
QMetaObject::invokeMethod(thread.file_log, "save_log", Qt::QueuedConnection);
return 0;
}
#include "main.moc"
- Dlaczego funkcja file_logger::save_log() nie wywołuje się dwa razy tylko jeden raz, pomimo tego, że są dwa wywołania invokeMethod?
- Czy wywołanie QThread::quit() nie powinno dodatkowo przetworzyć zakolejkowanych wywołań?
- Jeśli odkomentuję linijkę:
//QCoreApplication::processEvents();
to wtedy jest ok, są dwa wywołania save_log(). Czy to jest poprawne użycie?
4. Jeśli zamiast reimplementacji funkcji QThread::run() użyłbym QObject::moveToThread() dla obiektu klasy file_logger to wywołanie save_log() także nastąpiłoby tylko raz. Jak wtedy poradzić sobie z problemem bez reimplementacji run()?