美文网首页
c++ multithread and lock--part 3

c++ multithread and lock--part 3

作者: 前进中的奋斗猿 | 来源:发表于2019-11-19 21:49 被阅读0次

    本文将对<mutex>库进行详细的介绍
    多线程可以利用cpu并发执行提高运行效率,但是很明显会存在一个问题,那就是多个线程同时访问共享数据的时候,存在数据不一致的风险,这种现象也就是我们常说的“数据不安全”。为了保证数据的安全性,通常我们需要在访问共享数据的时候进行加锁操作,加锁可以保证在同一时刻在同一时刻只有一个线程对数据进行操作。TODO:MESI

    mutex互斥锁

    mutex是在多线程中用来保证数据一致性最简单的一种方式,我们先来看一下mutex到底是个什么东西。
    mutex是命名空间std下面的一个类,使用mutex需要引入<mutex>文件,但是在mutex文件中本身没有mutex类的定义。<mutex>中引入了<std_mutex.h>文件,类mutex就是在< std_mutex.h>中定义的, (注意:本系列文章示例代码的运行及代码分析都是基于MacOS,后续不再说明)。
    mutex继承自_mutex_base类,在_mutex_base类中定义了一个_gthread_mutex_t类型的_m_Mutex变量,_gthread_mutex_t实质上是源码中自定义的int类型的别名。所以显而易见,mutex便自动的拥有了_m_Mutex变量。
    mutex构造对象时会先调用_mutex_base类的构造函数,而在_mutex_base类的构造函数中会初始化_m_Mutex的值。
    mutex总共对外提供了四个成员函数,他们分别是:

    • lock():lock()方法里面的逻辑是
          int __e = __gthread_mutex_lock(&_M_mutex);
          if (__e)
          __throw_system_error(__e);
    

    而_gthread_mutex_lock(_gthread_mutex_t *_mutex)方法中的逻辑是:

      while (__sync_lock_test_and_set (_mutex, 1))
        asm volatile ("s_sleep\t1" ::: "memory");
      return 0;
    

    其中__sync_lock_test_and_set(_mutex, 1)是一个原子操作,用于将1写入_mutex,同时返回_mutex之前的值,当_mutex为1,即锁被占用时,会在此阻塞,直到_mutex被其他线程释放。由上述两段代码可知,lock()是阻塞式访锁模式。

    • try_lock():该方法跟lock()方法类似也是获取锁的方法,其包含逻辑为
    return !__gthread_mutex_trylock(&_M_mutex);
    

    继续跟,发现__gthread_mutex_trylock方法里的逻辑为

    __gthread_mutex_trylock (__gthread_mutex_t *__mutex)
    {
      return __sync_lock_test_and_set (__mutex, 1);
    }
    

    __gthread_mutex_trylock中没有循环,只是访问一次即返回。所以我们可以很清晰的知道,try_lock()是非是阻塞的。

    • unlock():释放锁的方法。
    • native_handle():方法里的逻辑是
    return &_M_mutex
    

    也就是获取_M_mutex的地址。

    相关文章

      网友评论

          本文标题:c++ multithread and lock--part 3

          本文链接:https://www.haomeiwen.com/subject/amogictx.html