程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
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語言代碼

為了方便,我們使用前面章回中演示互斥量的代碼,在該代碼的基礎上做一些小修改來演示死鎖。代碼如下:

首先定義兩個互斥量,互斥量是全局變量,方便線程使用。

#if MUTEX_ENABLE
pthread_mutex_t mutex_value1;
pthread_mutex_t mutex_value2;
#endif

接下來在主進程中(也就是main函數)初始化兩個互斥量:

    res = pthread_mutex_init(&mutex_value1,NULL);
    res = pthread_mutex_init(&mutex_value2,NULL);

在主進程的最後還要記得釋放與互斥量相關的資源:

#if MUTEX_ENABLE
    //destroy mutex
    res = pthread_mutex_destroy(&mutex_value1);
    res = pthread_mutex_destroy(&mutex_value2);
#endif

我們分別修改兩個線程的執行函數,該段代碼是核心代碼,請大家仔細閱讀:

// 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_value1);       // mutex1 is locking
        if(res != 0)
        {
            printf(" mutex1 lock failed \n");
        }
#endif
        read_data("Thread_1");

#if MUTEX_ENABLE
        res = pthread_mutex_lock(&mutex_value2); //mutex2 is locking
        if(res != 0)
        {
            printf(" mutex2 lock failed \n");
        }
#endif

#if MUTEX_ENABLE
        res = pthread_mutex_unlock(&mutex_value2);
        if(res != 0)
        {
            printf(" mutex2 unlock failed \n");
        }

        res = pthread_mutex_unlock(&mutex_value1);
        if(res != 0)
        {
            printf(" mutex1 unlock failed \n");
        }
#endif
        sleep(2);
    }

    printf("Thread ID::%u -----------E---------- \n",(unsigned int)thread_id);
    pthread_exit(&status); // end the thread
}
// the second thread function
void *thread_func2(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_value2);  //mutex 2 is locking
        if(res != 0)
        {
            printf(" mutex2 lock failed \n");
        }
#endif
        write_data("Thread_2");

#if MUTEX_ENABLE
        res = pthread_mutex_lock(&mutex_value1); //mutex 1 is locking
        if(res != 0)
        {
            printf(" mutex1 lock failed \n");
        }
#endif

#if MUTEX_ENABLE
        res = pthread_mutex_unlock(&mutex_value1);
        if(res != 0)
        {
            printf(" mutex1 unlock failed \n");
        }
#endif

#if MUTEX_ENABLE
        res = pthread_mutex_unlock(&mutex_value2);
        if(res != 0)
        {
            printf(" mutex2 unlock failed \n");
        }
#endif
        sleep(1);
    }

    printf("Thread ID::%u -----------E---------- \n",(unsigned int)thread_id);
    pthread_exit(&status); // end the thread
}

我們運行上面的程序,可以得到以下結果:

Create first thread     //創建第一個線程
Create second thread    //創建第二個線程
Thread ID::3076344640 -----------S---------- 
[Thread_1] start reading data  //第一個線程讀取數據,同時對互斥量一加鎖
Thread ID::3067951936 -----------S---------- 
[Thread_2] start writing data  //第二個線程修改數據,同時對互斥量二加鎖
[Thread_1] data = 0 
[Thread_1] end reading data    //第一個線程讀取數據結束,同時等待互斥量二被解鎖
[Thread_2] data = 1 
[Thread_2] end writing data    //第二個線程修改數據結束,同時等待互斥量一被解鎖
mutex2 can't be destroyed      //發生死鎖,程序運行錯誤

從上面的程序運行結果中可以看到,線程1鎖住了互斥量一,同時等待互斥量二;而線程2鎖住了互斥量二,同時等待互斥量一。這樣便造成了死鎖,進而引起了程序運行錯誤。

該程序是為了演示死鎖的原因專門寫的,這樣寫程序不合理,因為它不能同步線程,大家不要拘泥於程序的內容,重點是理解死鎖是如何發生的。

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

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


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