瞧一瞧Qt的QMutex(2)
上一篇说了那么多就是想表达QMutex是怎么运行的。不过QMutex的目的是保护数据,接下来就看看QMutex保护数据的例子吧。
例:
从QThread派生两个类Thread和Thread2,两个类的run函数分别如下:
int number = 0; //全局变量 void Thread::run() { number += 5; qDebug()<<"---------------"; int val = number*3; qDebug()<<"thread1"<<val; } void Thread2::run() { number += 3; qDebug()<<"---------------"; int val = number*2; qDebug()<<"therad2"<<val; }
两个线程的工作就是使用全局变量number来计算获得最终结果。若Thread线程先执行那么预期的结果将是Thread输出15。但是运行结果却是:
24是怎么来的呢?number在Thread线程中+=5变为了5,然后在Thread2线程中+=3变为了8,所以在Thread线程中再计算val的值时number已经变为了8,结果就是24了。
(说明:两个run函数中都有加qDebug()<<"---------------",目的是让两个线程交替执行,不然有可能线程在一个时间片内就完成了计算,结果就是预期的了。所以此处这个qDebug纯粹是为了写这个反例,没有实际意义。)
这时候就需要QMutex上场了,根据上一篇所说的,我们需要在两个线程中都加上QMutex。
void Thread::run() { mutex.lock(); number += 5; qDebug()<<"---------------"; int val = number*3; qDebug()<<"thread1"<<val; mutex.unlock(); } void Thread2::run() { mutex.lock(); number += 3; qDebug()<<"---------------"; int val = number*2; qDebug()<<"therad2"<<val; mutex.unlock(); }
运行结果:
QMutex虽好,但使用时也要小心一点,有lock就要unlock。不然的话别的线程就惨了。比如说把Thread::run中的mutex.unlock注释掉。那么运行结果就是:
只有Thread的结果打印出来了,那是因为Thread2还卡在mutex.lock这里,它还在问mutex你解锁了没.....