利用QMutex表示的互斥体给代码区加锁,可以保证该区中的代码在任何时候只被获得锁的那个线程执行。这对于避免因多个线程同时对共享数据执行写操作而导致的并发冲突是有效的。但有时多个线程只是想同时读取共享数据,这其实并不会引发冲突。最好能在加锁时区分读写,只在必须同步时同步,降低对并发性的削弱,提高运行性能。
QReadWriteLock类所表示的读写锁,在某种程度上满足了上述要求:
已加读锁:不能加写锁,但可以加读锁
已加写锁:不能加写锁,也不能加读锁
这就叫“读共享,写独占”。
xxxxxxxxxx
71void QReadWriteLock::lockForRead(); // 加读锁,其它线程可以再加读锁,但不能加写锁(阻塞)
2void QReadWriteLock::lockForWrite(); // 加写锁,其它线程既不能再加读锁(阻塞)也不能再加写锁(阻塞)
3bool QReadWriteLock::tryLockForRead(); // lockForRead的非阻塞版本
4bool QReadWriteLock::tryLockForWrite(); // lockForWrite的非阻塞版本
5bool QReadWriteLock::tryLockForRead(int timeout); // tryLockForRead的带超时版本
6bool QReadWriteLock::tryLockForWrite(int timeout); // tryLockForWrite的带超时版本
7void QReadWriteLock::unlock(); // 解锁
通过QtCreator,在C:\Users\Minwei\Projects\Qt路径下,创建名为ReadWriteLock的控制台(Console)项目。
C:\Users\Minwei\Projects\Qt\ReadWriteLock\main.cpp:
xxxxxxxxxx
851
2using namespace std;
3
4
5
6
7
8
9
10unsigned int g_cn = 0;
11QMutex g_mutex;
12QReadWriteLock g_rwlock;
13
14class WriterThread: public QThread
15{
16protected:
17 /* QMutex
18 void run()
19 {
20 for (unsigned int i = 0; i < 100000; i++) {
21 g_mutex.lock();
22 ++g_cn;
23 g_mutex.unlock();
24 }
25 }
26 */
27 // QReadWriteLock
28 void run()
29 {
30 for (unsigned int i = 0; i < 100000; i++) {
31 g_rwlock.lockForWrite();
32 ++g_cn;
33 g_rwlock.unlock();
34 }
35 }
36};
37
38class ReaderThread: public QThread
39{
40protected:
41 /* QMutex
42 void run()
43 {
44 for (unsigned int i = 0; i < 100000; i++) {
45 g_mutex.lock();
46 unsigned int cn = g_cn;
47 g_mutex.unlock();
48 }
49 }
50 */
51 // QReadWriteLock
52 void run()
53 {
54 for (unsigned int i = 0; i < 100000; i++) {
55 g_rwlock.lockForRead();
56 unsigned int cn = g_cn;
57 g_rwlock.unlock();
58 }
59 }
60};
61
62int main(int argc, char *argv[])
63{
64 QCoreApplication a(argc, argv);
65
66 WriterThread writer1, writer2;
67 ReaderThread reader1, reader2;
68
69 QTime time;
70 time.start();
71
72 writer1.start();
73 writer2.start();
74 reader1.start();
75 reader2.start();
76
77 writer1.wait();
78 writer2.wait();
79 reader1.wait();
80 reader2.wait();
81
82 cout << g_cn << ' ' << time.elapsed() << endl;
83
84 return a.exec();
85}
运行效果如图所示:
运行效果如图所示: