pthread_mutex_lock死锁以及进程重启仍然阻塞的问题

sanluojiyi3344 2015-03-08 05:32:39
各位大侠,小弟在一个LINUX上的应用中,发现我的服务在运行了一段时间之后无法响应新的请求,怀疑是底层的数据库接口在pthread_mutex_lock中阻塞了,现在一是需要排查到底为什么会出现这个问题,另外一个是出现这样的情况后,有遇到过即使重启应用也仍然是卡死的情况。

特别想请问一下,会否有我上面说的第二点的问题呢?
我的意思是如果我这个情况确实是因为某个线程lock之后没有unlock或者其他原因总之没有unlock
导致了其余的线程全在lock的地方被阻塞了,之后应用进程被kill -9杀掉之后,再重启仍然被阻塞?
有这样的可能吗?


底层的数据库接口基于OCCI封装(不要在意封装的那么烂),下面是代码

Environment* g_pDBOEnv = NULL; // 共享的OCCI上下文环境变量
int g_iDBOOpenConnCount = 0; // 总连接个数
bool g_bDBORecordLog = false; // 日志标识
Connection* g_pDBOConnList[1024]; // 共享的连接数组, 每个DB接口的调用者只获取到这个数组的下标
pthread_mutex_t g_fDBOLock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t g_fDBOGetLogMarkLock = PTHREAD_MUTEX_INITIALIZER;
char g_szDBORootPath[256];

int SCTDBConnect(const char* pDBInfo, int* piResType, char* pResInfo)
{
memset(g_szDBORootPath, 0x00, 256);
DBOGetRootPath(g_szDBORootPath);
pthread_mutex_lock(&g_fDBOGetLogMarkLock); // 此处就是获取日志标识
g_bDBORecordLog = bDBOGetLogMark();
pthread_mutex_unlock(&g_fDBOGetLogMarkLock);

sprintf(pLog, "%s", "Into SCTDBConnect!"); // 写日志
DBOWriteLog(pLog);

// 解析参数中的pDBInfo,用户名,密码,连接字符串
// ...

sprintf(pLog, "UserName: %s, Password: %s, Connstr: %s", strUname.data(), strPasswd.data(), strConnstr.data());
DBOWriteLog(pLog);

// 第二个锁,防止多线程获取到同一个连接,这个锁一直Lock,直到创建连接成功之后解锁
pthread_mutex_lock(&g_fDBOLock);
if (g_pDBOEnv == NULL)
{
// 此处是判断如果全局变量Environment* g_pEnv为空,则表示当前发起的连接是第一个连接
// 就需要创建Environment
g_pEnv = Environment::createEnvironment();
if (创建失败)
goto ENDOFCONN;

sprintf(pLog, "%s", "Create Environment In Object|Metexed Mode Successed");
DBOWriteLog(pLog);
}

if (g_pDBOEnv != NULL)
{
// 此处开始创建连接Connection*并且存放于全局数组中
iConnNo = iDBOGetIdleConnection(); // 获取一个下标
g_pDBOConnList[iConnNo] = g_pDBOEnv->createConnection(strUname, strPasswd, strConnstr);
if (创建失败)
goto ENDOFCONN;

g_iDBOOpenConnCount++;
sprintf(pLog, "%s", "Create Connection Successed");
DBOWriteLog(pLog);

sprintf(pLog, "Connection Number: %d", iConnNo);
DBOWriteLog(pLog);
}

ENDOFCONN:
sprintf(pLog, "%s", "Out Of SCTDBConnect!\n");
DBOWriteLog(pLog);
pthread_mutex_unlock(&g_fDBOLock); // 解锁

return iConnNo;
}

void SCTDBDisConnect(int iConnNo, int* piResType, char* pResInfo)
{
char pLog[10240];
memset(pLog, 0x00, 10240);

sprintf(pLog, "%s", "Into SCTDBDisConnect!");
DBOWriteLog(pLog);

pthread_mutex_lock(&g_fDBOLock);
if (g_pDBOEnv == NULL)
{
*piResType = 0;
goto ENDOFDISCONN;
}

if (g_pDBOConnList[iConnNo] != NULL)
{
sprintf(pLog, "%s", "Release Connection...");
DBOWriteLog(pLog);

g_pDBOEnv->terminateConnection(g_pDBOConnList[iConnNo]);
g_iDBOOpenConnCount--;
g_pDBOConnList[iConnNo] = NULL;

sprintf(pLog, "%s", "Release Connection Successed");
DBOWriteLog(pLog);
}
else
{
*piResType = 0;
goto ENDOFDISCONN;
}

if (g_iDBOOpenConnCount > 0)
{
*piResType = 0
goto ENDOFDISCONN;
}

sprintf(pLog, "%s", "Release Environment...");
DBOWriteLog(pLog);

Environment::terminateEnvironment(g_pDBOEnv);
g_pDBOEnv = NULL;

sprintf(pLog, "%s", "Release Environment Successed");
DBOWriteLog(pLog);

sprintf(pLog, "%s", "DisConnect Database Successed");
DBOWriteLog(pLog);

*piResType = 0;

ENDOFDISCONN:

sprintf(pLog, "%s", "Out Of SCTDBDisConnect!\n");
DBOWriteLog(pLog);
pthread_mutex_unlock(&g_fDBOLock);
return;
}
...全文
2527 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
柳鲲鹏 2019-03-19
  • 打赏
  • 举报
回复
1、使用状态判断.
2,使用超时加锁.
0xAaron 2015-09-22
  • 打赏
  • 举报
回复
我也遇到了死锁的问题了,重启应用后依然存在该问题,请问楼主是怎么解决的?
空的 2015-03-09
  • 打赏
  • 举报
回复
代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
sanluojiyi3344 2015-03-09
  • 打赏
  • 举报
回复
引用 2 楼 sanluojiyi3344 的回复:
[quote=引用 1 楼 erhou134 的回复:] 代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?[/quote] 你好!我在另外一个帖子里贴出了一些GDB的信息,不过我第一次使用GDB,不知道该如何调试,如果方便的话,还请你帮忙看下。。 地址:http://bbs.csdn.net/topics/390994763
sanluojiyi3344 2015-03-09
  • 打赏
  • 举报
回复
引用 3 楼 erhou134 的回复:
[quote=引用 2 楼 sanluojiyi3344 的回复:] [quote=引用 1 楼 erhou134 的回复:] 代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?[/quote] 额。。。这个可能性不大了,重现是可以的 代码有限,但我觉得问题不在这 另外想问的是 pLog 这个是全局变量吧,那写日志里面有锁吗,pLog不怕被覆盖吗[/quote] pLog不是全局变量 DBOWriteLog(pLog); pLog是作为参数传入的,不过这个写日志函数确实没有锁,存在有多个线程同时朝1个日志文件append的问题
sanluojiyi3344 2015-03-09
  • 打赏
  • 举报
回复
引用 3 楼 erhou134 的回复:
[quote=引用 2 楼 sanluojiyi3344 的回复:] [quote=引用 1 楼 erhou134 的回复:] 代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?[/quote] 额。。。这个可能性不大了,重现是可以的 代码有限,但我觉得问题不在这 另外想问的是 pLog 这个是全局变量吧,那写日志里面有锁吗,pLog不怕被覆盖吗[/quote] pLog不是全局变量 DBOWriteLog(pLog); pLog是作为参数传入的,不过这个写日志函数确实没有锁,存在有多个线程同时朝1个日志文件append的问题
空的 2015-03-09
  • 打赏
  • 举报
回复
引用 2 楼 sanluojiyi3344 的回复:
[quote=引用 1 楼 erhou134 的回复:] 代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?[/quote] 额。。。这个可能性不大了,重现是可以的 代码有限,但我觉得问题不在这 另外想问的是 pLog 这个是全局变量吧,那写日志里面有锁吗,pLog不怕被覆盖吗
sanluojiyi3344 2015-03-09
  • 打赏
  • 举报
回复
引用 1 楼 erhou134 的回复:
代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?
内容概要:本文系统讲解了OpenClaw Windows驱动开发的完整流程,旨在通过自研内核驱动扩展OpenClaw AI智能体框架的能力边界。文章从架构原理入手,介绍用户态与内核态协同的双层设计,阐述驱动在权限突破、硬件控制、系统级自动化等方面的核心价值。随后详细说明开发环境搭建、项目工程创建、核心模块设计(设备管理、IOCTL通信、内核执行、安全校验)及关键代码实现,并提供可运行的驱动模板。进一步涵盖驱动的编译签名、部署加载、调试优化方法,结合实战案例展示AI驱动的底层系统自动化应用,如进程管控、垃圾清理和硬件监控,最终总结开发要点与避坑指南。; 适合人群:具备Windows系统编程基础、熟悉C/C++和驱动开发的中高级研发人员,尤其是从事AI自动化、系统安全、底层运维相关工作的开发者。; 使用场景及目标:①实现OpenClaw在受限权限下的深度系统控制;②构建高可靠性、防检测的本地AI智能体控制系统;③开展硬件级自动化调度与企业终端统一管控; 阅读建议:此资源涉及内核级开发,操作风险较高,建议在虚拟机环境中进行测试,严格按照步骤配置开发与调试环境,重点关注安全校验与异常处理机制,确保驱动稳定性与系统安全性。

23,223

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧