std::lock_guard
这个类是一个互斥量的包装类,用来提供自动为互斥量上锁和解锁的功能,简化了多线程编程。
static std::mutex mutex; static std::weak_ptr<C2ComponentStore> platformStore; std::lock_guard<std::mutex> lock(mutex); std::shared_ptr<C2ComponentStore> store = platformStore.lock(); if (store == nullptr) { store = std::make_shared<C2PlatformComponentStore>(); platformStore = store; }
这段代码是android codec2中的代码,codec2/vndk/C2Store.cpp中可以看到。代码中std::lock_guard构造lock对象直接对mutex上锁。
std::lock_guard理解
-
在std::lock_guard对象构造时,传入的mutex对象会被当前线程锁住。
-
在lock_guard对象被析构时,它所管理的mutex对象会自动解锁,不需要程序员手动调用lock和unlock对mutex进行上锁和解锁操作。
-
lock_guard对象只是简化了mutex对象的上锁和解锁操作,方便线程对互斥量上锁,即在某个lock_guard对象的生命周期内,它所管理的锁对象会一直保持上锁状态。
-
lock_guard的生命周期结束之后,它所管理的锁对象会被解锁。
std::weak_ptr
static std::mutex mutex; static std::weak_ptr<C2ComponentStore> platformStore; std::lock_guard<std::mutex> lock(mutex); std::shared_ptr<C2ComponentStore> store = platformStore.lock(); if (store == nullptr) { store = std::make_shared<C2PlatformComponentStore>(); platformStore = store; }
还是看上面的代码,std::weak_ptr创建一个weak_ptr指针platformStore,随后调用lock函数,因为platformStore没有初始化,lock会返回一个空的shared_ptr指针。
std::weak_ptr理解
-
C++11标准虽然将 weak_ptr定位为智能指针的一种,但该类型指针通常不单独使用(没有实际用处),只能和 shared_ptr类型指针搭配使用。
-
当weak_ptr类型指针的指向和某一 shared_ptr指针相同时,weak_ptr指针并不会使所指堆内存的引用计数加1。
-
当weak_ptr指针被释放时,之前所指堆内存的引用计数也不会因此而减1。
也就是说,weak_ptr类型指针并不会影响所指堆内存空间的引用计数。除此之外,weak_ptr 模板类中没有重载*
和->
运算符,这也就意味着,weak_ptr类型指针只能访问所指的堆内存,而无法修改它。
创建一个 weak_ptr 指针,有以下 3 种方式:
std::weak_ptr<int> wp1;
凭借已有的 weak_ptr 指针,可以创建一个新的 weak_ptr 指针,例如:
std::weak_ptr<int> wp2 (wp1);
若 wp1 为空指针,则 wp2 也为空指针。反之,如果 wp1 指向某一 shared_ptr 指针拥有的堆内 存,则 wp2 也指向该块存储空间。
weak_ptr 指针更常用于指向某一 shared_ptr 指针拥有的堆内存,因为在构建 weak_ptr 指针对象时,可以利用已有的 shared_ptr 指针为其初始化。例如:
std::shared_ptr<int> sp (new int); std::weak_ptr<int> wp3 (sp);
由此,wp3 指针和 sp 指针有相同的指针。再次强调,weak_ptr 类型指针不会导致堆内存空间的引用计数增加或减少。
前面代码中的lock说明
lock() 如果当前weak_ptr已经过期,则该函数会返回一个空的shared_ptr指针;反之,该函数返回一个和当前weak_pt 指向相同的shared_ptr指针。
参考