C語言多線程編程 死鎖解析


 

1.假設有兩個線程

  A線程負責輸出奇數。B線程負責輸出偶數。

2.當A線程進入鎖定狀態是,主線程突然異常將A線程停止,這時將導致B線程也無法繼續執行,處於死鎖狀態。如下代碼:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t m;

void *runodd(void *d)
{
        int i=0;

        for(i=1;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("奇數:%d\n",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}
void *runeven(void *d)
{
        int i=0;
        for(i=0;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("偶數:%d\n",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}
main()
{
        pthread_t todd,teven;
        pthread_mutex_init(&m,0);
        pthread_create(&todd,0,runodd,0);
        pthread_create(&teven,0,runeven,0);
        sleep(5);
        printf("外部強制停止todd線程\n");
        pthread_cancel(todd);
        pthread_join(todd,(void**)0);
        pthread_join(teven,(void**)0);
        pthread_mutex_destroy(&m);
}

解決方法:
運用2個函數(其實是2個宏)

pthread_cleanup_push

pthread_cleanup_pop 這個對函數作用類似於atexit函數

注意:這不是函數而是宏。必須成對使用。

void pthread_cleanup_push(

void (*routine)(void *),//回調函數

void *arg //回調函數的參數

);

觸發調用routine的條件:

  1. 執行了exit()。
  2. 執行了pthread_cancel()
  3. pthread_cleanup_pop(1);//參數必須是1

 

 

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t m;
void handle(void *d)
{
        printf("退出后的調用!\n");
        pthread_mutex_unlock(&m);
}
void *runodd(void *d)
{
        int i=0;

        for(i=1;;i+=2)
        {
                pthread_cleanup_push(handle,0);
                pthread_mutex_lock(&m);
                printf("奇數:%d\n",i);
                usleep(100);
                pthread_mutex_unlock(&m);
                pthread_cleanup_pop(0);
        }
}
void *runeven(void *d)
{
        int i=0;
        for(i=0;;i+=2)
        {
                pthread_mutex_lock(&m);
                printf("偶數:%d\n",i);
                usleep(100);
                pthread_mutex_unlock(&m);
        }
}

 


免責聲明!

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



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