MutexLock 的封装
MutexLock类图
--------------------------------------------
-mutex_:pthread_mutex_t
-holder_:pid_t //线程的真实ID,用来表示拥有锁的线程
-----------------------------
<<create>>-MutexLock()
<<destroy>>-MutexLock
+isLockedByThisThread:bool // 当前线程是否拥有该锁
+assertLocked():void //断言当前线程是否拥有该锁
+lock():void
+unlock():void
+getPthreadMutex():pthread_mutex_t *
--------------------------------------------
MutexLockGuard类图封装
-------------------------
-mutex_:MutexLock &
-----------
<<create>>-MutexLockGurad(mutex:MutexLock&)
<<destroy>>-MutexLockGurad()
MutexLockGuard
MutexLockGuard 类图
-------------------
-mutex_:MutexLock&
<<create>>-MutexLockGuard(mutex:MutexLock&)
<<destroy>>-MutexLockGuard()
--------------------
MutexLock 和 MutexLockGuard的源代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/ Use of this
source code is governed by a BSD-style license// that can be found in the License file.//// Author: Shuo Chen (chenshuo at chenshuo dot com)#ifndef MUDUO_BASE_MUTEX_H#define MUDUO_BASE_MUTEX_H#include <muduo/base/CurrentThread.h>#include <boost/noncopyable.hpp>#include <assert.h>#include <pthread.h>namespace
muduo{class
MutexLock : boost::noncopyable //表示该类不能复制{ public: MutexLock() : holder_(0) { //初始化锁 int
ret = pthread_mutex_init(&mutex_, NULL); assert(ret == 0); (void) ret; } ~MutexLock() { //断言该锁是否还在使用 assert(holder_ == 0); //没用呗使用则销毁锁资源 int
ret = pthread_mutex_destroy(&mutex_); assert(ret == 0); (void) ret; } //测试当前线程是否拥有锁 bool
isLockedByThisThread() { return
holder_ == CurrentThread::tid(); }//断言锁 void
assertLocked() { assert(isLockedByThisThread()); } // internal usage//当前线程枷锁 void
lock() { pthread_mutex_lock(&mutex_); holder_ = CurrentThread::tid(); }//当前线程解锁 void
unlock() { holder_ = 0; pthread_mutex_unlock(&mutex_); } pthread_mutex_t* getPthreadMutex()
/* non-const */ { return
&mutex_; } private: pthread_mutex_t mutex_; pid_t holder_;};class
MutexLockGuard : boost::noncopyable //不可复制{ public://构造时负责枷锁
explicit
MutexLockGuard(MutexLock& mutex) : mutex_(mutex) { mutex_.lock(); }//虚构时负责解锁,但是并没有销毁mutex_ ~MutexLockGuard() { mutex_.unlock(); } private:// MutexLock &mutex 的生存期并不会被MutexLockGuard管理 //他们的关系是关联的。 // 聚合关系:表示A包含B // 组合关系:表示A包含B,并且负责B的生存期 MutexLock& mutex_;};}// Prevent misuse like:// MutexLockGuard(mutex_); 防止匿名对象// A tempory object doesn't hold the lock for long!#define MutexLockGuard(x) error "Missing guard object name"#endif // MUDUO_BA |
测试代码
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
#include <muduo/base/CountDownLatch.h>#include <muduo/base/Mutex.h>#include <muduo/base/Thread.h>#include <muduo/base/Timestamp.h>#include <boost/bind.hpp>#include <boost/ptr_container/ptr_vector.hpp>#include <vector>#include <stdio.h>using
namespace muduo;using
namespace std;MutexLock g_mutex;vector<int> g_vec;const
int kCount = 10*1000*1000;void
threadFunc(){ //插入kCount个整数 for
(int
i = 0; i < kCount; ++i) { //没循环一次加解锁一次,这里花费的时间会多点 MutexLockGuard lock(g_mutex); g_vec.push_back(i); }}int
main(){ //最多8 个线程 const
int kMaxThreads = 8;、 //预留8千多万个整数 , 300多m g_vec.reserve(kMaxThreads * kCount); //登记一个时间戳 Timestamp start(Timestamp::now()); //插入kCount多个整数 for
(int
i = 0; i < kCount; ++i) { g_vec.push_back(i); } //单线程 统计插入kCount个整数所用时间 printf("single thread without lock %f\n", timeDifference(Timestamp::now(),
start)); start = Timestamp::now(); threadFunc(); printf("single thread with lock %f\n", timeDifference(Timestamp::now(),
start)); for
(int
nthreads = 1; nthreads < kMaxThreads; ++nthreads) { //这是一个指针vector,存放的是Thread乐行的指针 //智能指针,释放threads时,它里面的对象也会被销毁 boost::ptr_vector<Thread> threads; g_vec.clear(); start = Timestamp::now(); /* 第一次 1 个线程, 第二次2个线程.....,不同线程个数时所花费的时间 **/ for
(int
i = 0; i < nthreads; ++i) { threads.push_back(new
Thread(&threadFunc)); //启动最后一个对象的线程,其实就是每增加一个,然后就执行它 threads.back().start(); } //等待线程的结束 for
(int
i = 0; i < nthreads; ++i) { threads[i].join(); } //计算时间差 printf("%d thread(s) with lock %f\n", nthreads, timeDifference(Timestamp::now(),
start)); }} |
程序输出
|
1
2
3
4
5
6
7
8
9
10
11
|
[root@localhost bin]# ./mutex_test
single thread
without lock 1.512640single thread
with lock 1.3058071 thread(s) with lock 0.6855712 thread(s) with lock 3.3812973 thread(s) with lock 4.6407764 thread(s) with lock 5.3833975 thread(s) with lock 7.8972236 thread(s) with lock 21.7980797 thread(s) with lock 23.351875[root@localhost bin]#
|
本文介绍了一个基于pthread的MutexLock及MutexLockGuard类的实现。MutexLock用于线程同步,通过记录持有者PID确保互斥访问;MutexLockGuard作为RAII风格的锁守卫,简化了加解锁操作。

被折叠的 条评论
为什么被折叠?



