我有一个服务器端客户端程序,其中有多个线程在服务器和客户端。有不同数量的客户端和服务器(如3台服务器(副本),10台客户端)。我在这个程序中调试源文件。我认为存在某种类型的死锁,可能有以下几种:帮助需要与pthreads调试
互斥锁已被服务器方法占用,来自客户端的请求调用一个想要再次获取互斥锁的服务器方法。
该程序由测试脚本启动,该脚本生成服务器和客户端,并使客户端向服务器发送特定请求。我已经使用在代码的可疑区域下面的代码,看看是否有一个僵局,但它似乎没有工作,即代码既不进入块:
if (pthread_mutex_lock(&a_mutex) == EDEADLK) {
cout<<"couldnt acquire lock."<<endl;
}
else cout<<"acquired lock"<<endl;
我试着调试(通过附加一个运行服务器进程)与gdb。我为a_mutex添加了“display”和“watch”(在gdb的不同运行中)。我得到以下形式的结果:
1: a_mutex = {__data = {__lock = 2, __count = 0, __owner = 4193, __kind = 0, __nusers = 2,
{__spins = 0, __list = {__next = 0x0}}},
__size = "\002\000\000\000\000\000\000\000a\020\000\000\000\000\000\000\002\000\000 \000\000\000\000", __align = 2}
我不知道在上面的输出中的所有事物的意义,但我可以看到一个线程(4193)持有的互斥。我看到该线程的回溯(剪切):
#0 0xb8082430 in __kernel_vsyscall()
#1 0xb7e347a6 in nanosleep() from /lib/tls/i686/cmov/libc.so.6
#2 0xb7e345be in sleep() from /lib/tls/i686/cmov/libc.so.6
#3 0x0804cb59 in class1::method1 (this=0xbfa9fe6c, clt=1, id=
{static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xb7c9c11c "l/%\b"}})
at file1.cc:33
我不知道如何以及错误在哪里。
我将高度赞赏有以下问题的任何帮助:
- 什么是调试这样的条件/程序的好方法吗?
- 我该如何检测死锁状态(例如,锁正在被锁定而未被释放)?
- 在这样的多进程程序中,有没有更好的使用gdb的方法? (即检查所有进程中的状态?配置gdb以在进程开始之前监视/显示变量?)
- 因为当服务器启动后(通过测试脚本)将gdb与服务器连接在一起时,服务器可能已经超越了我想要检查的代码。我试图在可疑区域之前添加睡眠(20)以帮助我使用gdb,但我认为这不是一个好方法。我也认为打开多个终端,手动启动服务器和客户端并检查每个终端的状态也不是一个好主意(如果我错了,请纠正我)。
PS:我已经读过question了。
非常感谢。
我个人使用了英特尔线程检查器。我发现它非常有用捕获死锁 – onof 2010-07-14 11:43:42
我也使用过英特尔线程检查器。这个hellgrind工具(Valgrind的一部分)也很棒。 – 2010-07-14 13:41:22
这看起来不像死锁,而只是争用。你有第二个互斥体在那里被收购吗?如果是这样,请确保它们以相同的顺序*被锁定。 – 2010-07-14 20:11:50