pthread_cancel的带来的一个死锁问题(验证)
来源:互联网 发布:织梦5.7sp2最新漏洞 编辑:程序博客网 时间:2024/06/05 08:13
代码来自:http://blog.csdn.net/wwyyxx26/article/details/9018473
如下:
test_deadlock.c
#include <unistd.h>#include <pthread.h>#include <stdio.h>#include <stdlib.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;void* thread0( void* arg ){ printf( "T0:Enter\n" ); printf( "T0:Before lock\n" ); pthread_mutex_lock(&mutex); printf( "T0:Before pthread_cond_wait\n" ); pthread_cond_wait(&cond,&mutex); printf( "T0:After pthread_cond_wait\n" ); pthread_mutex_unlock(&mutex); printf( "T0:Exit\n" ); return NULL;//pthread_exit(NULL);}void* thread1( void* arg ){ printf( "T1:Enter\n" ); sleep(10); printf( "T1:After Sleep\n" ); int err = pthread_mutex_trylock(&mutex); if( err == 0 ) { printf( "T1:Acquire Lock Success\n" ); } else { printf( "T1:Acquire Lock Fail\n" ); pthread_exit(NULL); } printf( "T1:Before ptread_mutex_broadcast\n" ); pthread_cond_signal(&cond); printf( "T1:After pthread_mutex_broadcast\n" ); pthread_mutex_unlock(&mutex); printf( "T1:Exit\n" ); return NULL;//pthread_exit(NULL);}int main(){ pthread_t tid[2]; if( pthread_create(&tid[0],NULL,&thread0,NULL) != 0 ) { exit(1); } if( pthread_create(&tid[1],NULL,&thread1,NULL) != 0 ) { exit(1); } sleep(5); //不加这句有可能出现不死锁的情况 printf( "Main:Before pthread_cancel tid[0]\n" ); pthread_cancel(tid[0]); printf( "Main:After pthread_cancel tid[0]\n" ); printf( "Main:Before pthread_join tid[0]\n" ); pthread_join(tid[0],NULL); printf( "Main:After pthread_join tid[0]\n" ); printf( "Main:Before pthread_join tid[1]\n" ); pthread_join(tid[1],NULL); printf( "Main:After pthread_join tid[1]" ); pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); return 0;}
相对于原文中的做出了一点修改
把thread1中的pthread_mutex_lock 修改为pthread_mutex_trylock,pthread_cond_broadcast修改为pthread_cond_signal
编译:
CentOS 6.3 64-bit
gcc test_deadlock.c -lpthread -o test
在运行测试时,都是按照预期出现了死锁,死锁原因在原文中也说得很清楚,就是在thread0在cancellation point(pthread_cond_wait)时,对mutex又加上了锁,thread1这时从sleep中苏醒,再次去acquire mutex,这时就出现了死锁。
(在代码中把thread1中pthread_mutex_trylock恢复为pthread_mutex_lock才会出现死锁,这里的现象为acquire mutex失败线程直接退出)。
正常情况下:
pthread_mutex_lock ->pthread_cond_wait->pthread_mutex_unlock
相当于:pthread_mutex_lock->(pthread_mutex_unlock->pthread_mutex_lock)->pthread_mutex_unlock
在pthread_cancel调用以后,在pthread_cond_wait中的cleanup中会将mutex重新上锁。
POSIX cancellation points参见:
http://stackoverflow.com/questions/433989/posix-cancellation-points
文中提到了pthread_cond_wait,如果thread0是在 pthread_cond_wait这个取消点退出的话,这是会出现死锁的情况。
由于pthread_cond_wait最后是调用的是pthread_mutex_lock,推断pthread_mutex_lock才是真正意义上的cancellation point
测试:
在main线程pthread_cancel前取消sleep(5); 这样在运行时就可能会出现thread0运行至pthread_cond_wait前main thread先运行至pthread_cancel,测试发现会有一定几率(取决于main线程和thread0切换)出现mutex不死锁的情况(并未输出”Before pthread_cond_wait”)
结论:
pthread_mutex_lock也是POSIX cancellation point,pthread_cond_wait因为调用pthread_mutex_lock也成为了 cancellation point.
- pthread_cancel的带来的一个死锁问题(验证)
- 一个 pthread_cancel 引起的线程死锁
- 一个 pthread_cancel 引起的线程死锁
- pthread_cancel引起的死锁
- pthread_cancel引起的死锁
- 6、一个 pthread_cancel 引起的线程死锁【整理转载】
- 一个 pthread_cancel 引起的线程死锁【整理转载】
- 一个 pthread_cancel 引起的线程死锁【整理转载】
- linux下记一次使用gdb对死锁问题的定位以及pthread_cancel使用的建议
- 一个死锁的问题
- 改正 抢占式camera的可能带来死锁问题
- mysql中 insert …select …带来的死锁问题
- mysql中 insert …select …带来的死锁问题
- mysql 的一个死锁问题
- css嵌套带来的一个问题
- docker1.5带来的一个小问题
- jackson的一个并发死锁的问题
- 一个验证的问题
- Android studio 自定义logcat各种信息输出颜色
- NGUI研究院之Sprite精灵与精灵动画的使用(二)
- static和extern
- Python 学习(3)---Python标准异常总结
- 嵌入式开发 tftp使用方法
- pthread_cancel的带来的一个死锁问题(验证)
- hdu 1596 find the safest road (dijkstra)
- 利用mysql里的show global status和show variables来优化mysql的配置参数
- 《ArcGIS Runtime SDK for Android开发笔记》——(7)、示例代码arcgis-runtime-samples-android的使用
- 运算符重载 - 判断平行
- Android各种访问权限Permission详解
- onSaveInstanceState和onRestoreInstanceState
- weibo feed
- maven的使用