程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 一起talk C栗子吧(第一百一十八回:C語言實例--線程死鎖二)

一起talk C栗子吧(第一百一十八回:C語言實例--線程死鎖二)

編輯:關於C語言

一起talk C栗子吧(第一百一十八回:C語言實例--線程死鎖二)



各位看官們,大家好,上一回中咱們說的是線程死鎖的例子,這一回咱們繼續說該例子。閒話休提,言歸正轉。讓我們一起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函數避免了死鎖的發生。

看官們,正文中就不寫代碼了,完成的代碼放到了我的資源中,大家可以下載使用。

各位看官,關於線程死鎖的例子咱們就說到這裡。欲知後面還有什麼例子,且聽下回分解 。


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved