QThread, два тупика QTimer и QMutex - PullRequest
0 голосов
/ 04 августа 2020

У меня есть QObject с методом, защищенным QMutex. Этот метод можно запускать напрямую из многих потоков. И у меня есть еще один QObject, живущий в другом QThread с двумя QTimers. Таймеры имеют разные интервалы и метод вызова timeout () первого объекта.

Может случиться так, что таймеры истекают одновременно и блокируют один и тот же QMutex из одного и того же потока. Как такое возможно? Почему один код QThread запускается параллельно самому себе?

Я устранил эту проблему, разместив таймеры в разных потоках. Но почему QThread может выполнять код таким образом?

void Module::exec(const QString command)
{
    qDebug("---> run from %X", QThread::currentThreadId());
    QMutexLocker lock(&m_mutex);
    //do the work    
}

class AutoCalibration : public QObject
{
    Q_OBJECT
public:
    explicit AutoCalibration(QObject *parent = 0);
protected:
    QTimer *m_timerTimeout;
    QTimer *m_timerPolling;
    QThread *m_worker;
}

AutoCalibration::AutoCalibration(QObject *parent) : QObject(),
    m_timerTimeout(new QTimer()),
    m_timerPolling(new QTimer()),
    m_worker(new QThread(parent))
{
    m_timerTimeout->moveToThread(m_workwr);
    m_timerTimeout->setInterval(15000);

    m_timerPolling->moveToThread(m_workwr);
    m_timerPolling->setInterval(10000);

    connect(m_timerTimeout, &QTimer::timeout, this, &AutoCalibration::calibrate, Qt::DirectConnection); // run Module::exec() with one argument
    connect(m_timerPolling, &QTimer::timeout, this, &AutoCalibration::requestProp, Qt::DirectConnection); // run Module::exec() with another argument

    connect(m_worker, &QThread::finished, m_timerTimeout, &QTimer::stop);
    connect(m_worker, &QThread::finished, m_timerPolling, &QTimer::stop);

    connect(m_worker, SIGNAL(started()), m_timerTimeout, SLOT(start()));
    connect(m_worker, SIGNAL(started()), m_timerPolling, SLOT(start()));

    m_worker->start();
}
...