c++析构时上锁会发生什么呢?

前言

上篇文章 c++ this指针的有效性 验证后,笔者思维发散想到假如在类析构时对互斥锁上锁,会发生什么呢?带着这个疑问,笔者进行下列验证。

  1. 构造一个类,在类内部起一个使用循环加锁解锁的线程。同时,在类的外部也起一个使用循环加锁解锁的线程。
  2. 在1的基础上,类的析构中对互斥锁进行加锁。

结果

  1. 第一种情况,程序正常。
  2. 第二种情况,程序崩溃。崩溃步骤是互斥锁析构时抛出异常。结论:互斥锁析构时,不能是已加锁状态。

示例代码(欢迎讨论)

#include <atomic>
#include <thread>
#include <functional>
#include <iostream>
#include <map>
#include <unordered_map>
#include <memory>
#include <mutex>

class MutexDeconstructTest {
public:
    MutexDeconstructTest() {
        h_ = std::thread([this]() {
            while (!stopped) {
                {
                    std::lock_guard<std::mutex> l(m_);
                    std::cout << "MutexDeconstructTest.h_ run locked" << std::endl;
                }
            }
            std::cout << "MutexDeconstructTest.h_ stopped = true, exit..." << std::endl;
            });
    }

    ~MutexDeconstructTest() {
        stopped = true;
        if (h_.joinable()) {
            h_.join();
        }
        m_.lock();
    }

    void TryLock() {
        std::lock_guard<std::mutex> l(m_);
        std::cout << "MutexDeconstructTest::TryLock locked" << std::endl;
    }

private:
    std::atomic_bool stopped{false};
    std::mutex m_;
    std::thread h_;
};


int main(int argc, char* argv[]) {
    for (size_t i = 0; i < 100000; ++i) {
        auto mdt = std::make_shared<MutexDeconstructTest>();
        std::atomic_bool stopped = false;
        auto tmp_h = std::thread([&]() {
            while (!stopped) {
                std::cout << "main::for::lambda run..." << std::endl;
                mdt->TryLock();
                }
            });
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        stopped = true;
        tmp_h.join();
        tmp_h = std::thread();
        mdt.reset();
        mdt = nullptr;
    }

    return 0;
}

结尾

  • 想法验证,问题记录。
  • 如果觉得还不错,你的点赞关注加收藏便是笔者继续更新的最大动力哦^_^
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值