我正在使用的软件中遇到一种奇怪的行为。它是一个用C ++编写的实时机器控制器,在Linux上运行,它正在广泛使用多线程。
当我运行程序而不要求它是实时的时,一切都像我期望的那样工作。但当我要求它切换到它的实时模式时,有一个明显可重现的错误,让应用程序崩溃。它必定是一些死锁 - 我想,因为它是一个碰到超时并最终触发断言的互斥锁。
我的问题是,如何打倒这个。从产生的核心看回溯并不是很有帮助,因为问题的原因在于过去的某个地方。
以下代码执行“正常”和“实时”行为之间的切换:
在main.cpp中(简化后,通过断言检查返回码):
if(startAsRealtime){
struct sched_param sp;
memset(&sp, 0, sizeof(sched_param));
sp.sched_priority = 99;
sched_setscheduler(getpid(), SCHED_RR, &sp);}
在每个线程中(简化后,通过断言检查返回码):
if(startAsRealtime){
sched_param param;
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_getschedparam(&attr, ¶m);
param.sched_priority = priority;
pthread_attr_setschedpolicy(&attr, SCHED_RR);
pthread_attr_setschedparam(&attr, ¶m);}
提前致谢
答案 0 :(得分:1)
如果你使用glibc
作为你的C库,你可以使用问题Is it possible to list mutexs which a thread holds的答案来找出持有超时互联网的线程。这应该开始缩小范围 - 然后你可以检查那个线程并找出它为什么不放弃互斥量。
答案 1 :(得分:0)
你的一个实时线程可能在循环中旋转(而不是屈服),从而使其他线程匮乏并导致互斥锁超时。
当您切换到“实时模式”时,也可能存在竞争条件。实时模式中的事件发生时间恰好会触发某种死锁。
如果您有获得多级锁定的地方,或者递归锁定,那么这些应该是您怀疑的第一个地方。
如果您真的不知道问题所在,请尝试二进制搜索方法来解决问题。递归地删除一半功能,直到将其缩小到实际问题。您可能需要模拟一些暂时删除的子系统。
您可以将此二进制搜索技术应用于互斥锁获取超时,以找出哪一个是罪魁祸首。