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;
}
...全文
2420 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用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 的回复:
代码看不出来啥问题啊 有可能死锁的就是一个线程做到一半挂了,锁没人解了 重启死锁 有可能,那种锁在共享内存里的,共享内存没清,就可能有
你好,感谢回复! 那你说的这种情况有办法可以模拟重现出来吗?

23,217

社区成员

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

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