C++ 记一次结构体中使用互斥(std::mutex) 引发的程序异常

服务内容

  • c++后台服务, 接口接收数据同步(每次只能可能有一个请求在执行)。

引发异常现象

  • 线上版本服务一直正常执行,突然有一天服务接收不到请求了。前端所有请求都收不到了。

解决思路

  • 第一次出现。运营说已经半个小时无法操作了。慌得一批,赶紧查看,只发现后台接收不到数据了。不管了先重启服务。重启了,又一切正常了。跟运营小姐姐说,好了但是我还不知道原因。
  • 开始怀疑是框架内网关处理的问题,其他服务有没有问题。先不管了还有很多事情没做,先做其他的。
  • 隔一天第二次出现。还是怀疑框架内网关有问题。先让框架的同事查看下,框架的同事说没有问题我先重启了保证客户能用。
  • 开始讨论。出现这种问题的原因大概率是死锁了。因为每次只有一个请求能处理,现在是所有的请求都收不到了,也就是说又一次的请求没有返回,这才会导致其他的请求无法接受。开始逐一排查死锁问题。花了一天全都查了一遍没有明显的死锁问题。想不通,下班了回去再看,郁闷。回家的路上骑着小电驴回顾一天的死锁。想到程序中有一个服务重置的机智。这个地方会clear掉所有的数据(数据结构为std::map<int,struct>,struct中有一个std::mutex),会不会出现我正在遍历map的value,同时另外一个线程正好执行了clear。这就会导致我遍历的map的mutex是一个无效对象,从而导致死锁。开心,回去测试一下。

上测试代码

  • 测试单元test.hpp
#ifndef __TEST_SOME_HPP__
#define __TEST_SOME_HPP__

#include <iostream>
#include <mutex>
#include <map>
#include "BaseFunc.h"
#include <thread>
#include <list>
using namespace std;

#define aaaa(a) #a
#define aabb(a,b) a##b

void run_TestSome()
{
    int64_t iAccID;
    cout << iAccID << endl;
}


#pragma region 测试mutex

struct StructMutex_s
{
    std::mutex _mux;
    std::map<int,int> _mapData;
    void add(int i, int j) {
        std::unique_lock<std::mutex> lck(_mux);
        _mapData[i] = j;
    }
};

std::map<int, StructMutex_s> g_mapStructMutexData;

void printStructMutexData()
{
    for (auto& item : g_mapStructMutexData)
    {
        basefunc::Sleep(600);
        std::unique_lock<std::mutex> lck(item.second._mux);
        for (auto& data : item.second._mapData) {
            cout << data.first <<";"<<data.second << endl;
        }
    }
    
}

void clearStructMutexData()
{
    basefunc::Sleep(1000);
    g_mapStructMutexData.clear();
    cout << "clear finish" << endl;
}

void run_TestStructMutex(){
    for (int i = 0; i < 10; ++i) {
        g_mapStructMutexData[i].add(i, i+1);
    }

    std::list<std::thread> listThread;
    std::thread t1(
        [&](){
            clearStructMutexData();
        });
    std::thread t2(
        [&](){
            printStructMutexData();
        });
    t1.join();
    t2.join();
}


#pragma endregion

#endif
  • main
#include "test.hpp"
int main()
{
	run_TestStructMutex();
	return 0;
}

总结

  • 死锁问题不一定是显示的lock之后没有unlock,还有可能互斥相已经不存在了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值