(14)muduo_base库源码分析:MutexLock类,MutexLockGuard类,Condition类

1.MutexLock类图,MutexLockGuard类图

  • MutexLock类图
    在这里插入图片描述

  • MutexLockGuard类图,此类更加常用,使用RAII技法封装
    在这里插入图片描述

  • MutexLock类与MutexLockGuard类的lock方法和unlock方法说明


void f()
{
	mutex.lock()
	...
	if(条件)
	{
		return;//这里直接return,如果忘记umutex.unlock,会造成死锁
	}
	mutex.unlock;
}


void f()
{
	MutexLockGuard lock(mutex);//在构造函数中加锁了
	...
	if(条件)
	{
		return;//这里直接return,那么lock对象的生命周期就结束了,自动调用析构函数解锁
	}
	
}//这里返回,和上面的return解释一样
  • 类之间的关系:3个
    (1)关联关系
    MutexLockGuard类使用了mutex类中的lock和unlock方法
    (2)聚合关系
    整体与局部的关系
    (3)组合关系
    整体与局部的关系,以及还负责对对象的销毁,就是组合关系

2.Mutex.h分析

  • 位置:14\jmuduo\muduo\base\Mutex.h
// 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
{
//MutexLock类继承至noncopyable,表示不可以拷贝的
class MutexLock : boost::noncopyable
{
 public:
  MutexLock()
    : holder_(0)//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();//将当前线程的tid保存至holder_
  }

  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();//构造函数中调用lock
  }

  ~MutexLockGuard()
  {
    mutex_.unlock();//析构函数中调用unlock
  }

 private:

  MutexLock& mutex_;//MutexLockGuard对象生命期结束的时候,mutex_对象的生命期未结束
};

}

// Prevent misuse like:
// MutexLockGuard(mutex_);//不运行构造一个匿名的mutex对象,要不然会报错
// A tempory object doesn't hold the lock for long!
#define MutexLockGuard(x) error "Missing guard object name"

#endif  // MUDUO_BASE_MUTEX_H

3.Mutex_test.cc分析

  • 位置:14\jmuduo\muduo\base\tests\Mutex_test.cc
//#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()
{
  for (int i = 0; i < kCount; ++i)
  {
    MutexLockGuard lock(g_mutex);//MutexLockGuard在构造函数中lock,在析构函数中unlock
    g_vec.push_back(i);
  }
}

int main()
{
  
  const int kMaxThreads = 8;
  g_vec.reserve(kMaxThreads * kCount);//预留8千万个整数=3亿bit,相当于300M左右的内存


  //没有锁的测试
  Timestamp start(Timestamp::now());//登记时间戳
  for (int i = 0; i < kCount; ++i)
  {
    g_vec.push_back(i);
  }

  printf("single thread without lock %f\n", timeDifference(Timestamp::now(), start));//插入1千万个整数,看需要多少时间


  //有锁的测试
  //下面的这个是主线程
  start = Timestamp::now();
  threadFunc();
  printf("single thread with lock %f\n", timeDifference(Timestamp::now(), start));

  //下面的是创建子线程
  for (int nthreads = 1; nthreads < kMaxThreads; ++nthreads)
  {
    boost::ptr_vector<Thread> threads;//释放时,能够销毁存放在vector的对象
    g_vec.clear();
    start = Timestamp::now();

    //只有1个线程时,依次类推
    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));
  }
}

4.测试

  • 需要修改内容:14\jmuduo\muduo\base\tests\CMakeLists.txt
。。。。
##新增
add_executable(mutex_test Mutex_test.cc)
target_link_libraries(mutex_test muduo_base)
##新增
。。。。。

-执行结果:
在这里插入图片描述

19:54

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章