各位看官們,大家好,上一回中咱們說的是線程死鎖的例子,這一回咱們繼續說該例子。閒話休提,言歸正轉。讓我們一起talk C栗子吧!
看官們,我們在上一回中介紹了死鎖的概念,並且詳細分析了死鎖發生的原因,同時給出了偽代碼來演示死鎖。今天我們將把偽代碼轉換為實際的C語言代碼。
為了方便,我們使用前面章回中演示互斥量的代碼,在該代碼的基礎上做一些小修改來演示死鎖。代碼如下:
// the first thread function
void *thread_func1(void *param)
{
int i = 0;
int res = 0;
pthread_t thread_id;
thread_id = pthread_self();
printf("Thread ID::%u -----------S---------- \n",(unsigned int)thread_id);
while(i++ < 4)
{
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value);
if(res != 0)
{
printf(" mutex lock failed \n");
}
#endif
read_data("Thread_1");
//這部分加鎖的代碼是在原來代碼的基礎上新添加的,表示對互斥量進行第二次加鎖
#if MUTEX_ENABLE
res = pthread_mutex_lock(&mutex_value);
if(res != 0)
{
printf(" mutex lock failed \n");
}
#endif
#if MUTEX_ENABLE
res = pthread_mutex_unlock(&mutex_value);
if(res != 0)
{
printf(" mutex unlock failed \n");
}
#endif
sleep(2);
}
printf("Thread ID::%u -----------E---------- \n",(unsigned int)thread_id);
pthread_exit(&status); // end the thread
}
下面是程序的運行結果,請大家參考:
Create first thread //創建第一個線程
Create second thread
Thread ID::3076418368 -----------S----------
[Thread_1] start reading data //第一個線程運行,並且開始讀取數據。在讀取數據前已經對互斥量加鎖
Thread ID::3068025664 -----------S----------
[Thread_1] data = 0
[Thread_1] end reading data //第一個線程讀取數據結束,接著對互斥量第二次加鎖,這時發生了死鎖
mutex can't be destroyed //程序中發生死鎖後,不能正確釋放互斥量相關的資源
從上面的程序運行結果中可以看到,程序發生了死鎖,讀取和修改數據的線程都沒有正常運行,並且還出現了運行錯誤。由此可見,死鎖造成的後果很嚴重。
接下來我們演示使用pthread_mutex_trylock函數來避免死鎖。我們還使用上面程序中的代碼,只需要把代碼中的pthread_mutex_lock函數替換為pthread_mutex_trylock函數就可以,其它的代碼保持不變。
下面是修改代碼後程序的運行結果:
Create first thread //創建第一個線程
Create second thread //創建第二個線程
Thread ID::3076127552 -----------S----------
[Thread_1] start reading data //第一個線程運行,並且開始讀取數據。在讀取數據前已經對互斥量加鎖
Thread ID::3067734848 -----------S----------
[Thread_1] data = 0
[Thread_1] end reading data
mutex lock failed //第一個線程讀取數據結束,接著對互斥量第二次加鎖,這時加鎖失敗
[Thread_2] start writing data
[Thread_2] data = 1
[Thread_2] end writing data
[Thread_1] start reading data
[Thread_1] data = 1
[Thread_1] end reading data
mutex lock failed //每次重復加鎖時都會發生加鎖失敗,但是不會發生死鎖
[Thread_2] start writing data
[Thread_2] data = 2
[Thread_2] end writing data
[Thread_1] start reading data
[Thread_1] data = 2
[Thread_1] end reading data
mutex lock failed
[Thread_2] start writing data
[Thread_2] data = 3
[Thread_2] end writing data
[Thread_1] start reading data
[Thread_1] data = 3
[Thread_1] end reading data
mutex lock failed
[Thread_2] start writing data
[Thread_2] data = 4
[Thread_2] end writing data
Thread ID::3076127552 -----------E---------- //第一個線程結束
Thread ID::3067734848 -----------E---------- //第二個線程結束
從上面的程序運行結果中可以看到,對互斥量進行第二個加鎖時沒有發生死鎖,而是加鎖失敗,此時程序正常運行,讀取和修改共享數據的線程都正常運行直到結束為止。由此可見,我們使用pthread_mutex_trylock函數避免了死鎖的發生。
看官們,正文中就不寫代碼了,完成的代碼放到了我的資源中,大家可以下載使用。
各位看官,關於線程死鎖的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。