递归锁和非递归锁

1.递归锁和非递归锁含义


  递归锁:在同一个线程可以多次获取同一个锁,不会产生死锁。

  非递归锁:在同一个线程中,加锁后不可以再次获取该锁,如果获取可能产生死锁。

2.常用锁的递归和非递归属性


  linux下的pthread_mutex_t是非递归锁,但是可以通过在创建互斥量时设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t设置为递归锁。

  读写锁是非递归锁。

  尽量不要使用递归锁,即同一个线程中,尽量不要重复锁定同一个锁,读锁也不可以。

  另外加锁最好避免互相嵌套,否则也容易死锁。

3.一个死锁


  下面是使用读写锁导致的死锁问题,因为读写锁是非递归锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void *process()
{
    pthread_rwlock_wrlock(&g_lock); // 2.加写锁,此时会一直等待,导致死锁
     
    pthread_rwlock_unlock(&g_lock); // 释放写锁
    return NULL;
}
 
int main()
{
    pthread_rwlock_t  g_lock;
 
    pthread_rwlock_rdlock(&g_lock);     // 1.第1次加读锁
 
    create_thread(process);             // 创建线程
    sleep(5);                           // 等待几秒
 
    pthread_rwlock_rdlock(&g_lock);     // 3.第2次加读锁,此时会一致等待,导致死锁
 
    pthread_rwlock_unlock(&g_lock);     // 释放第1次的读锁
    pthread_rwlock_unlock(&g_lock);     // 释放第2次的读锁
}

4.另一个死锁


  下面这个死锁出现的原因是,如果一个线程已经加读锁,然后第二个线程加写锁,则会导致第三个线程加读锁加不上,因为此时写锁优先级高。

  但是在linux下面的读写锁不会死锁。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
三个锁: lock_a, lock_b, lock_c
 
process1()
{
    write_lock(lock_a);
    write_lock(lock_b);
    write_unlock(lock_b);
    write_unlock(lock_a);
}
 
process2()
{
    read_lock(lock_b);
    read_lock(lock_c);
    read_unlock(lock_c);
    read_unlock(lock_b);
}
 
process3()
{
    read_lock(lock_c);
    read_lock(lock_a);
    read_unlock(lock_a);
    read_unlock(lock_c);
}
 
process4()
{
    write_lock(lock_c);
    write_unlock(lock_c);
}
 
process1: a_write[1     ]  ->  b_write [加锁不上,第3步已经加读锁]
process2: b_read [2     ]  ->  c_read  [加锁不上,第4步写锁先开始等的,优先级高]
process3: c_read [3     ]  ->  a_read  [加锁不上,第1步已经加写锁]
process4: c_write[4 加锁不上,第3步已经加读锁]

  

posted on   能量星星  阅读(1123)  评论(0编辑  收藏  举报

努力加载评论中...

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示