网上Qt多线程同步的一种普遍误识

Youtube上有一个很出名的Qt视频教程,讲得简练精要。但是在他讲到的Qt线程同步一集的时候,我凭着自己的经验,感觉他讲得是错的。于是在网上大范围的搜索“qt线程同步”这个关键字,试图找到一些线索,以证明视频教程中的错误。但是看了很多个博客之后,我发现大家都是千篇一律,很是吃惊。真是误导大家。所以特意写这篇文章来证实一下。 首先我们要知道为什么要用线程同步?那是因为在多线程编程里面,会有一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。 在这里我们引用一个网上较为流行的一个例子。如下所示,,这是一个线程的实现:

class Thread : public QThread { public:Thread();void stop(); protected:(); private:bool m_stop; }; Thread::Thread() {m_stop = false; } void Thread::stop() {m_stop = true; } void Thread::run() {while (!m_stop){sleep(1);qDebug(“vic.MINg!”);}qDebug(“end!”); }

Qt中的线程是以对象的形式存在的。如果我们在main函数中生成几个此类的线程对象,如下:

Thread m1;Thread m2;Thread m3;m1.start();m2.start();m3.start();

那么m1,m2,m3之间会有我们自己定义的共享数据存在吗?显然,从C++对象的概念出发来理解,他们之间是不会存在这些共享数据的。因为各个对象会维护各自对象空间里的变量。按上面例子中的代码来看,m1,m2,m3分别有着一个自己的m_stop,那我们还有必要对这个m_stop来做同步操作吗?显然是没有必要的。而网上的多数例子,以及那个Youtube的视频却对m_stop做了同步操作,引用原文的代码:

//thread.h头文件,添加互斥量对象 private:…QMutex mutex; }; void Thread::run() {forever {mutex.lock();if (m_stop) {m_stop = false;mutex.unlock();break;}mutex.unlock();qDebug(“vic.MINg!”);}qDebug(“end!”); } void Thread::stop() {mutex.lock();m_stop = true;mutex.unlock(); }

文中的意思是使用QMutex保护上面的线程类的m_stop布尔变量,我们就纳闷了,一个不被多个线程共享的数据还需要被保护呢?其中一个线程对象把这个变量改变了,其他线程对象的这个变量又不会受到什么影响。这样做又有什么意义可言。 且不争论这个,这还不算最大的问题所在。最大的问题是定义的互斥变量也是作为类的成员变量来定义的。那么由这个线程类生成m1,m2,m3对象势必是三个不相干的互斥量,你怎么可能因为把m1的互斥量上锁,而不能让m2对自己的互斥量上锁呢?也就是说,这三个线程压根不是被同一个互斥量来协调,以达到同步的。因此,网上的多数Qt多线程同步的例子可以说是错误的。 线程同步,首先你必须保证多个线程受控于共有的一个互斥量,我们想达到共有一个互斥量需要将互斥量定义为静态变量才对。如下所示:

class Thread : public QThread{public:Thread();~Thread();private:void run();public:QString name;static QMutex m;//只有这种情况下,互斥量才是被所有此类线程所共享的};//这一句最好定义在对应的cpp文件中,避免重复定义QMutex MyThread::m; //静态对象必须定义

由C++对象的特征我们可以知道,以上的QMutex对象在所有的此类线程中是共享的,通过这样去修改,才真正地多个线程同步。为了避免大家被网上错误的讲解所误解,免得把多线程同步按照他们的方式去写,特发此文。 如果哪里有不对,请大家给我指出,我将不胜感激!! 我把随便参考的一个错误链接贴出来: Youtube视频链接:?list=PL2D1942A4688E9D63

但我想说,我做了一个善良的平凡女子,并且一直在爱,

网上Qt多线程同步的一种普遍误识

相关文章:

你感兴趣的文章:

标签云: