Привет всем.
В своем рабочем проекте я столкнулся с тем, что посланный сигнал не доходит до получателя. Есть два потока и один из по завершении некоторой работы сообщает второму об этом. Все хорошо было до тех пор, пока я не стал использовать мьютексы для дополнительный синхронизации. Теперь я понимаю, что проблема была прежде всего в дизайне. Но если не брать это в расчет хотелось все же понять что неправильно и что является источником проблемы. Я написал тестовый проект, который в общем показывает суть проблемы.
#ifndef TESTCLASSES_H
#define TESTCLASSES_H
#include <QtTest/QTest>
#include<QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>
class Worker :public QObject
{
Q_OBJECT
public:
QMutex _mut;
void init()
{
qDebug() << "Worker::init - lock mutex";
_mut.lock();
}
public slots:
void process()
{
qDebug() << "Worker::process - trying to lock mutex";
QMutexLocker m(&_mut);
qDebug() << "Worker::process - mutex has been released ";
}
void releasemutex()
{
qDebug() << "Worker::releasemutex - unlock mutex";
_mut.unlock();
}
};
class Finisher :public QObject
{
Q_OBJECT
public slots:
void process()
{
qDebug() << "Finisher::process - start sleeping";
QTest::qSleep(2000);
qDebug() << "Finisher::process - end sleeping,emit finished";
emit finished();
}
signals:
void finished();
};
class Controller :public QObject
{
Q_OBJECT
Worker worker;
Finisher finisher;
QThread wThread;
QThread fThread;
public:
void init()
{
qDebug() << "Controller::init start";
connect(&finisher, SIGNAL(finished()), &worker, SLOT(releasemutex()));
worker.init();
worker.moveToThread(&wThread);
finisher.moveToThread(&fThread);
connect(&fThread, SIGNAL(started()), &finisher, SLOT(process()));
connect(&wThread, SIGNAL(started()), &worker, SLOT(process()));
connect(&fThread, SIGNAL(finished()), &finisher, SLOT(deleteLater()));
connect(&wThread, SIGNAL(finished()), &finisher, SLOT(deleteLater()));
wThread.start();
fThread.start();
qDebug() << "Controller::init end";
}
};
#endif // TESTCLASSES_H
#include <QCoreApplication>
#include "TestClasses.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Controller controller;
controller.init();
return a.exec();
}
Если убрать мьютекс то все окей. Я не понимаю почему он лочит процесс Worker . Ведь поток Finisher посылает сигнал finished, что по идее дергает метод releasemutex