如何在派生类中正确使用QMutex?

时间:2018-03-01 21:35:22

标签: c++ multithreading qt

我有以下课程(简化):

class BaseJob : public QObject
{
   Q_OBJECT
public:
   QMutex *getMutex() const {
       return &mutex;
   }
virtual ~BaseJob() = 0;

private:
   static QMutex mutex;
};

class Worker1 : public QObject
{
   Q_OBJECT
public:
   Worker1(QMutex *mutex) : m_mutex(mutex) {}
public slots:
   void work() {
      QMutexLocker lock(m_mutex);
       qInfo() << "worker1 is running";
   }
private:
   QMutex *m_mutex;
};

class Worker2 : public QObject
{
   Q_OBJECT
public:
   Worker2(QMutex *mutex) : m_mutex(mutex) {}
public slots:
   void work() {
      QMutexLocker lock(m_mutex);
      qInfo() << "worker2 is running";
   }
private:
   QMutex *m_mutex;
};

class Job1 : public BaseJob
{
   Q_OBJECT
public:
   Job1() : m_worker(new Worker1(this->getMutex())) {
       connect(this, SIGNAL(doWork()),
               m_worker, SLOT(work()));
       connect(&m_thread, SIGNAL(finished()),
               m_worker, SLOT(deleteLater()));
       m_worker->moveToThread(&m_thread);
       m_thread.start();
   }
   void work() {
       emit doWork();
   }
   virtual ~Job1() {
       m_thread.quit();
       m_thread.wait();
   }
signals:
   void doWork();

private:
   QThread m_thread;
   Worker1 *m_worker;
};

class Job2 : public BaseJob
{
   Q_OBJECT
public:
   Job2() : m_worker(new Worker2(this->getMutex())) {
       connect(this, SIGNAL(doWork()),
               m_worker, SLOT(work()));
       connect(&m_thread, SIGNAL(finished()),
               m_worker, SLOT(deleteLater()));
       m_worker->moveToThread(&m_thread);
       m_thread.start();
   }
   void work() {
       emit doWork();
   }
   virtual ~Job2() {
       m_thread.quit();
       m_thread.wait();
   }
signals:
   void doWork();

private:
   QThread m_thread;
   Worker2 *m_worker;
};

然后我使用:

调用作业
void Widget::on_pushButton_clicked()
{
    m_job1->work();
    m_job2->work();
}

工作人员需要有一个公共插槽,work()应该受到关键部分的保护,以防止对同一文件的并发写访问。

到目前为止,我已在基类QMutex中添加了BaseJob,因此我可以通过Worker1Worker2 ctor传递对此互斥锁的引用,最后在里面work()功能。

它有效,但有更好的方法来实现这一目标吗?

感谢。

0 个答案:

没有答案