在最近的项目中,一些多线程的知识与一个线程需要锁定多个资源有关,与多线程死锁问题有关。 这里总结一下

发生死锁的方法有多种,并非只有当一个线程与多个锁相关时才会发生死锁,一个锁也可能会发生死锁。

1、第一种常见情况是上锁后没有解锁。 锁后可能真的忘记了unlock,这样的东西很少见也很容易发现。 但是,过程有时可能无法像我们预想的那样顺利完成。 可能是因为lock和unlock之间的代码异常终止,锁定后无法解除锁定,后续程序无法实现对该锁定的请求,死锁正在等待。

解决方案: c语言使用所谓的Autolock本地对象。 在对象的构造函数中为lock,在析构函数中为unlock。 因为是在堆栈上创建的对象,所以系统会自动执行析构函数,并在程序异常关闭时执行析构函数以释放资源。

2、第二,在同一线程上对同一资源多次调用lock函数。 某些互斥锁定对象没有线程所有权属性,如windows信号量Semaphores。 也就是说,某个线程获得信号量后,在释放信号量之前不能进入信号量保护领域。 如果信号量只有1,则如果同一线程两次调用WaitForSingleObject,则第二次调用将阻止程序并发生死锁。

三种情况是我们通常说的情况。 有2个线程,有线程1和线程2,有2个锁a和b,线程1持有a后等待b,与此同时线程1持有b后等待a。 无法释放两个线程都拥有的锁,也无法获取等待的锁。

避免死锁一般针对第三种情况。

1、避免在同一线程上同时锁定两个关键资源。 但是,在业务上必须这样做的情况下也没办法。

2、一种可能的方法是通过使多个线程锁定多个锁的顺序相同来避免死锁的发生。 例如,如果对线程1线程a资源执行锁定,对b资源执行锁定,则线程2使用相同的顺序也不会发生死锁。

3、另一个可行的方案是获取所有需要一次获取的锁,如果不能一次获取,则等待。 我以为在linux上可以用pthread_mutex_trylock函数来实现。 伪代码如下所示(对于两个锁)。

while(true ) Pthread_mutex_lock ) Mutexa; if (0==pthread _ mutex _ trylock (mutexb ) ) /成功获取所有锁break; } else { //解除拥有的锁定,继续等待pthread_mutex_unlock(mutexa ); //延迟一段时间后继续请求usleep (10 * 1000 ); }//业务代码. Pthread_mutex_unlock(mutexa ); thread_mutex_unlock(mutexb ); 4、也可以使用挂起的超时机制。 如果等待一个锁没有得到很长时间,释放自己拥有的所有锁,避免死锁。 该方法是处理指标感难治、发生死锁后的情况,而不是有效预防死锁。

5、另一个据说是死锁检测机制。 这个太虚了,太深奥了,我们也不知道检查方法,所以还是在预防方面下功夫比较好。

大小单双稳赢技巧/p>

1、避免在同一线程上同时锁定两个关键资源。 但是,在业务上必须这样做的情况下也没办法。

2、一种可能的方法是通过使多个线程锁定多个锁的顺序相同来避免死锁的发生。 例如,如果对线程1线程a资源执行锁定,对b资源执行锁定,则线程2使用相同的顺序也不会发生死锁。

3、另一个可行的方案是获取所有需要一次获取的锁,如果不能一次获取,则等待。 我以为在linux上可以用pthread_mutex_trylock函数来实现。 伪代码如下所示(对于两个锁)。

while(true ) Pthread_mutex_lock ) Mutexa; if (0==pthread _ mutex _ trylock (mutexb ) ) /成功获取所有锁break; } else { //解除拥有的锁定,继续等待pthread_mutex_unlock(mutexa ); //延迟一段时间后继续请求usleep (10 * 1000 ); }//业务代码. Pthread_mutex_unlock(mutexa ); thread_mutex_unlock(mutexb ); 4、也可以使用挂起的超时机制。 如果等待一个锁没有得到很长时间,释放自己拥有的所有锁,避免死锁。 该方法是处理指标感难治、发生死锁后的情况,而不是有效预防死锁。

5、另一个据说是死锁检测机制。 这个太虚了,太深奥了,我们也不知道检查方法,所以还是在预防方面下功夫比较好。