遞歸鎖和非遞歸鎖


1.遞歸鎖和非遞歸鎖含義


  遞歸鎖:在同一個線程可以多次獲取同一個鎖,不會產生死鎖。

  非遞歸鎖:在同一個線程中,加鎖后不可以再次獲取該鎖,如果獲取可能產生死鎖。

2.常用鎖的遞歸和非遞歸屬性


  linux下的pthread_mutex_t是非遞歸鎖,但是可以通過在創建互斥量時設置PTHREAD_MUTEX_RECURSIVE屬性,將pthread_mutex_t設置為遞歸鎖。

  讀寫鎖是非遞歸鎖。

  盡量不要使用遞歸鎖,即同一個線程中,盡量不要重復鎖定同一個鎖,讀鎖也不可以。

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

3.一個死鎖


  下面是使用讀寫鎖導致的死鎖問題,因為讀寫鎖是非遞歸鎖。

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下面的讀寫鎖不會死鎖。

三個鎖: 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步已經加讀鎖]

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM