IPC组件的分装之互斥锁(14)

本文介绍了一个基于pthread的MutexLock及MutexLockGuard类的实现。MutexLock用于线程同步,通过记录持有者PID确保互斥访问;MutexLockGuard作为RAII风格的锁守卫,简化了加解锁操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.512640
single thread with lock 1.305807
1 thread (s) with lock 0.685571
2 thread (s) with lock 3.381297
3 thread (s) with lock 4.640776
4 thread (s) with lock 5.383397
5 thread (s) with lock 7.897223
6 thread (s) with lock 21.798079
7 thread (s) with lock 23.351875
[root@localhost bin]#


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值