我正在研究多线程网络服务器应用程序。目前,我遇到了锁定恢复问题。如果一个线程在持有锁时意外死亡,比如一个互斥锁,rwlock,自旋锁......等,是否有可能从另一个线程恢复锁,而不必进入锁结构本身并手动取消所有者的关联从锁。我想不必去这个极端来清除它,因为这将使代码不可移植。我试图通过对违规线程执行pthread_kill并查看返回代码来强制更改锁定所有者。但即使使用PTHREAD_MUTEX_ERRORCHECK的互斥锁类型属性,如果锁定线程已退出,我仍然无法从另一个线程获得对互斥锁的控制。如果在线程挽救时更新某个内部表,这可能会出现问题,因为它最终会导致整个服务器应用程序停止。
我已广泛使用Google,即使在这里,我也会收到相互矛盾的信息。我可以探索的任何建议或想法?
这是在使用clang-llvm编译器的FreeBSD 9.3上。
答案 0 :(得分:1)
对于在进程(PTHREAD_PROCESS_SHARED
)之间共享的互斥锁,您可以设置它们PTHREAD_MUTEX_ROBUST
...但是您仍然遇到由互斥锁保护的状态的问题可能无效 - 取决于申请。
对于没有在进程之间共享的互斥锁,没有标准的“健壮性”概念,因为一个线程不能自发地死掉 - 一个线程将一直运行,直到它被取消,它退出或进程退出或者模具
您可以使用:
void pthread_cleanup_push(void (*routine)(void*), void *arg);
void pthread_cleanup_pop(int execute);
如果线程被取消或者在持有互斥锁时退出,则安排释放互斥锁 - 例如:
pthread_mutex_lock(&foo) ; // as now
pthread_cleanup_push(pthread_mutex_unlock, &foo) ; // extra step
....
pthread_cleanup_pop(true) ; // replacing the pthread_mutex_unlock()
但是,仍然需要仔细考虑线程被取消或退出时互斥锁保护的数据的状态!!
你可能会更好地检查线程为什么需要这个,并且可能会排除任何错误/异常处理以将错误/异常传递出临界区(让关键部分干净利落)。