linux-C下的死锁检测(pthread_mutex_)

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <pthread.h>  
  5.   
  6. #define MAX_COUNT 64  
  7.   
  8. typedef struct tagMute   
  9. {  
  10.     pthread_mutex_t  mutex;  
  11.     char file[128];  
  12.     int  line;  
  13.     int  mute_status;  
  14.     struct tagPLAYER * tag_player;  
  15. } T_MUTE;  
  16.   
  17. typedef struct tagPLAYER  
  18. {  
  19.     T_MUTE *player_mux;  
  20. }T_PLAYER;  
  21.   
  22. typedef struct tagLIST  
  23. {  
  24.     int     list_count;  
  25.     T_MUTE *list[MAX_COUNT];  
  26. }T_LIST;  
  27.   
  28. typedef struct tagARG  
  29. {  
  30.   
  31.     int shareA, shareB;  
  32.     int count;  
  33.     T_PLAYER *player_A, *player_B;  
  34. }T_ARG;  
  35.   
  36. T_LIST *list;  
  37.   
  38. #define PLAYER_MUXTEX_INIT(x) do {\  
  39. T_PLAYER *player = (T_PLAYER *)x;\  
  40. pthread_mutex_init(&(player->player_mux->mutex), NULL);\  
  41. memset(player->player_mux->file, 0, sizeof(player->player_mux->file));\  
  42. player->player_mux->line = 0;\  
  43. player->player_mux->mute_status = 0;\  
  44. player->player_mux->tag_player = player;\  
  45. list->list[list->list_count++] = player->player_mux;\  
  46. }while(0)  
  47.   
  48. #define PLAYER_MUXTEX_LOCK(x) do {\  
  49.     T_PLAYER *player = (T_PLAYER *)x;\  
  50.     pthread_mutex_lock(&(player->player_mux->mutex));\  
  51.     strncpy(player->player_mux->file, __FILE__, sizeof(player->player_mux->file));\  
  52.     player->player_mux->line =  __LINE__;\  
  53.     player->player_mux->mute_status = 1;\  
  54. }while (0)  
  55.   
  56. #define PLAYER_MUXTEX_UNLOCK(x) do {\  
  57.     T_PLAYER *player = (T_PLAYER *)x;\  
  58.     player->player_mux->mute_status = 0;\  
  59.     pthread_mutex_unlock(&player->player_mux->mutex);\  
  60. }while(0)  
  61.   
  62. #define PLAYER_MUXTEX_DESTROY do {\  
  63.     while(list->list_count){\  
  64.         pthread_mutex_destroy(&list->list[list->list_count-1]->mutex);\  
  65.         free(list->list[list->list_count-1]);\  
  66.         list->list_count--;\  
  67.     }\  
  68. }while(0)  
  69.   
  70. void handle_dead_lock(void)  
  71. {  
  72.     int index;  
  73. flag:  
  74.     printf("Please input unlock index: ");  
  75.     scanf("%d", &index);  
  76.   
  77.     if((index >= 0) &&(index < list->list_count))  
  78.     {  
  79.         PLAYER_MUXTEX_UNLOCK(list->list[index]->tag_player);  
  80.     }  
  81.     else  
  82.     {  
  83.         printf("Input error!\n");  
  84.         goto flag;  
  85.     }  
  86. }  
  87.   
  88. void *loop_detect_deadlock_thread(void *arg)  
  89. {    
  90.     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);  
  91.     pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);  
  92.   
  93.     T_ARG *argDetect = (T_ARG *)arg;  
  94.     int i = 0;  
  95.     while(1)  
  96.     {  
  97.         T_MUTE *mutex = list->list[i];  
  98.   
  99.         pthread_mutex_lock(&mutex->mutex);  
  100.         argDetect->count ++;  
  101.         pthread_mutex_unlock(&mutex->mutex);  
  102.   
  103.           
  104.         i = (++i) % list->list_count;  
  105.         pthread_testcancel();  
  106.         sleep(1);  
  107.     }  
  108. }  
  109.   
  110. void *loop_detect_count_thread(void *arg)  
  111. {  
  112.     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);  
  113.     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);  
  114.   
  115.     T_ARG *argCount = (T_ARG *)arg;  
  116.     do  
  117.     {  
  118.         int temp = argCount->count;  
  119.         sleep(5);  
  120.         if(temp == argCount->count)  
  121.         {  
  122.             printf("dead lock!\n");  
  123.             int i = 0;  
  124.             for(i = 0; i < list->list_count; i++)  
  125.             {  
  126.                 if(list->list[i]->mute_status)  
  127.                 {  
  128.                     printf("%d\tlock at %s:%d\n",i, list->list[i]->file, list->list[i]->line);  
  129.                 }  
  130.             }  
  131.             handle_dead_lock();  
  132.         }  
  133.     }while(1);  
  134. }  
  135.   
  136. void * thread_fun_A(void * arg)  
  137. {  
  138.     T_ARG *argA = (T_ARG *)arg;  
  139.     PLAYER_MUXTEX_LOCK(argA->player_A);  
  140.     printf("threadA lock   playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);  
  141.   
  142. //    printf("shareA = shareA(%d) + 2\n", shareA);  
  143.     argA->shareA += 2;  
  144.       
  145.   
  146.     sleep(1);  
  147.     PLAYER_MUXTEX_LOCK(argA->player_B);  
  148.     printf("threadA lock   playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);  
  149.   
  150. //    printf("shareA = shareB(%d) + 2\n", shareB);  
  151.     argA->shareA = argA->shareB + 2;  
  152.       
  153.       
  154.     PLAYER_MUXTEX_UNLOCK(argA->player_B);  
  155.     printf("threadA unlock playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);  
  156.       
  157.     PLAYER_MUXTEX_UNLOCK(argA->player_A);  
  158.     printf("threadA unlock playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);  
  159. }  
  160.   
  161. void * thread_fun_B(void * arg)  
  162. {  
  163.     T_ARG *argB = (T_ARG *)arg;  
  164.       
  165.     PLAYER_MUXTEX_LOCK(argB->player_B);  
  166.     printf("threadB lock   playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);  
  167.   
  168. //    printf("shareB = shareB(%d) + 3\n", shareB);  
  169.     argB->shareB += 3;  
  170.       
  171.       
  172.     sleep(1);  
  173.     PLAYER_MUXTEX_LOCK(argB->player_A);  
  174.     printf("threadB lock   playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);  
  175.   
  176. //    printf("shareB = shareA(%d) + 3\n", shareA);  
  177.     argB->shareB = argB->shareA + 3;  
  178.       
  179.       
  180.     PLAYER_MUXTEX_UNLOCK(argB->player_A);  
  181.     printf("threadB unlock playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);  
  182.   
  183.     PLAYER_MUXTEX_UNLOCK(argB->player_B);  
  184.     printf("threadB unlock playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);  
  185. }  
  186.   
  187. void init(T_ARG *arg)  
  188. {  
  189.     arg->shareA = 0;  
  190.     arg->shareB = 0;  
  191.     arg->count = 0;  
  192.   
  193.     list = (T_LIST *)malloc(sizeof(T_LIST));  
  194.     list->list_count = 0;  
  195.       
  196.     arg->player_A = (T_PLAYER *)malloc(sizeof(T_PLAYER));  
  197.     arg->player_B = (T_PLAYER *)malloc(sizeof(T_PLAYER));  
  198.   
  199.     arg->player_A->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));  
  200.     arg->player_B->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));  
  201.   
  202.     PLAYER_MUXTEX_INIT(arg->player_A);  
  203.     PLAYER_MUXTEX_INIT(arg->player_B);  
  204. }  
  205.   
  206. void free_player(T_ARG *arg)  
  207. {  
  208.     free(arg->player_A);  
  209.     free(arg->player_B);  
  210.       
  211.     free(arg);  
  212.   
  213.     free(list);  
  214. }  
  215. int main(int argc, char * argv[])  
  216. {  
  217.     T_ARG *arg = (T_ARG *)malloc(sizeof(T_ARG));  
  218.       
  219.     init(arg);  
  220.       
  221.     int ret = -1;  
  222.       
  223.     pthread_t threadA, threadB, thread_detect_deadlock, thread_detect_count;  
  224.     ret = pthread_create(&threadA, NULL, thread_fun_A, (void *)arg);   
  225.     if(ret != 0)  
  226.     {  
  227.         printf("Pthread create error!\n");  
  228.     }  
  229.   
  230.     ret = pthread_create(&threadB, NULL, thread_fun_B, (void *)arg);   
  231.     if(ret != 0)  
  232.     {  
  233.         printf("Pthread create error!\n");  
  234.     }  
  235.   
  236.     ret = pthread_create(&thread_detect_deadlock, NULL, loop_detect_deadlock_thread, (void *)arg);   
  237.     if(ret != 0)  
  238.     {  
  239.         printf("Pthread create error!\n");  
  240.     }  
  241.   
  242.     ret = pthread_create(&thread_detect_count, NULL, loop_detect_count_thread, (void *)arg);   
  243.     if(ret != 0)  
  244.     {  
  245.         printf("Pthread create error!\n");  
  246.     }  
  247.       
  248.     pthread_join(threadA, NULL);  
  249.     pthread_join(threadB, NULL);  
  250.   
  251.     pthread_cancel(thread_detect_count);  
  252.     pthread_cancel(thread_detect_deadlock);  
  253.     pthread_join(thread_detect_count, NULL);  
  254.     pthread_join(thread_detect_deadlock, NULL);  
  255.       
  256.     PLAYER_MUXTEX_DESTROY;  
  257.   
  258.     printf("shareA: %d, shareB: %d\n", arg->shareA, arg->shareB);  
  259.     free_player(arg);  
  260. }  
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define MAX_COUNT 64

typedef struct tagMute 
{
    pthread_mutex_t  mutex;
    char file[128];
    int  line;
    int  mute_status;
    struct tagPLAYER * tag_player;
} T_MUTE;

typedef struct tagPLAYER
{
    T_MUTE *player_mux;
}T_PLAYER;

typedef struct tagLIST
{
    int     list_count;
    T_MUTE *list[MAX_COUNT];
}T_LIST;

typedef struct tagARG
{

    int shareA, shareB;
    int count;
    T_PLAYER *player_A, *player_B;
}T_ARG;

T_LIST *list;

#define PLAYER_MUXTEX_INIT(x) do {\
T_PLAYER *player = (T_PLAYER *)x;\
pthread_mutex_init(&(player->player_mux->mutex), NULL);\
memset(player->player_mux->file, 0, sizeof(player->player_mux->file));\
player->player_mux->line = 0;\
player->player_mux->mute_status = 0;\
player->player_mux->tag_player = player;\
list->list[list->list_count++] = player->player_mux;\
}while(0)

#define PLAYER_MUXTEX_LOCK(x) do {\
    T_PLAYER *player = (T_PLAYER *)x;\
    pthread_mutex_lock(&(player->player_mux->mutex));\
    strncpy(player->player_mux->file, __FILE__, sizeof(player->player_mux->file));\
    player->player_mux->line =  __LINE__;\
    player->player_mux->mute_status = 1;\
}while (0)

#define PLAYER_MUXTEX_UNLOCK(x) do {\
    T_PLAYER *player = (T_PLAYER *)x;\
    player->player_mux->mute_status = 0;\
    pthread_mutex_unlock(&player->player_mux->mutex);\
}while(0)

#define PLAYER_MUXTEX_DESTROY do {\
    while(list->list_count){\
        pthread_mutex_destroy(&list->list[list->list_count-1]->mutex);\
        free(list->list[list->list_count-1]);\
        list->list_count--;\
    }\
}while(0)

void handle_dead_lock(void)
{
    int index;
flag:
    printf("Please input unlock index: ");
    scanf("%d", &index);

    if((index >= 0) &&(index < list->list_count))
    {
        PLAYER_MUXTEX_UNLOCK(list->list[index]->tag_player);
    }
    else
    {
        printf("Input error!\n");
        goto flag;
    }
}

void *loop_detect_deadlock_thread(void *arg)
{  
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);

    T_ARG *argDetect = (T_ARG *)arg;
    int i = 0;
    while(1)
    {
        T_MUTE *mutex = list->list[i];

        pthread_mutex_lock(&mutex->mutex);
        argDetect->count ++;
        pthread_mutex_unlock(&mutex->mutex);

        
        i = (++i) % list->list_count;
        pthread_testcancel();
        sleep(1);
    }
}

void *loop_detect_count_thread(void *arg)
{
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);

    T_ARG *argCount = (T_ARG *)arg;
    do
    {
        int temp = argCount->count;
        sleep(5);
        if(temp == argCount->count)
        {
            printf("dead lock!\n");
            int i = 0;
            for(i = 0; i < list->list_count; i++)
            {
                if(list->list[i]->mute_status)
                {
                    printf("%d\tlock at %s:%d\n",i, list->list[i]->file, list->list[i]->line);
                }
            }
            handle_dead_lock();
        }
    }while(1);
}

void * thread_fun_A(void * arg)
{
    T_ARG *argA = (T_ARG *)arg;
    PLAYER_MUXTEX_LOCK(argA->player_A);
    printf("threadA lock   playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);

//    printf("shareA = shareA(%d) + 2\n", shareA);
    argA->shareA += 2;
    

    sleep(1);
    PLAYER_MUXTEX_LOCK(argA->player_B);
    printf("threadA lock   playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);

//    printf("shareA = shareB(%d) + 2\n", shareB);
    argA->shareA = argA->shareB + 2;
    
    
    PLAYER_MUXTEX_UNLOCK(argA->player_B);
    printf("threadA unlock playerB, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
    
    PLAYER_MUXTEX_UNLOCK(argA->player_A);
    printf("threadA unlock playerA, shareA = %d, shareB = %d\n", argA->shareA, argA->shareB);
}

void * thread_fun_B(void * arg)
{
    T_ARG *argB = (T_ARG *)arg;
    
    PLAYER_MUXTEX_LOCK(argB->player_B);
    printf("threadB lock   playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);

//    printf("shareB = shareB(%d) + 3\n", shareB);
    argB->shareB += 3;
    
    
    sleep(1);
    PLAYER_MUXTEX_LOCK(argB->player_A);
    printf("threadB lock   playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);

//    printf("shareB = shareA(%d) + 3\n", shareA);
    argB->shareB = argB->shareA + 3;
    
    
    PLAYER_MUXTEX_UNLOCK(argB->player_A);
    printf("threadB unlock playerA, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);

    PLAYER_MUXTEX_UNLOCK(argB->player_B);
    printf("threadB unlock playerB, shareA = %d, shareB = %d\n", argB->shareA, argB->shareB);
}

void init(T_ARG *arg)
{
    arg->shareA = 0;
    arg->shareB = 0;
    arg->count = 0;

    list = (T_LIST *)malloc(sizeof(T_LIST));
    list->list_count = 0;
    
    arg->player_A = (T_PLAYER *)malloc(sizeof(T_PLAYER));
    arg->player_B = (T_PLAYER *)malloc(sizeof(T_PLAYER));

    arg->player_A->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));
    arg->player_B->player_mux = (T_MUTE *)malloc(sizeof(T_MUTE));

    PLAYER_MUXTEX_INIT(arg->player_A);
    PLAYER_MUXTEX_INIT(arg->player_B);
}

void free_player(T_ARG *arg)
{
    free(arg->player_A);
    free(arg->player_B);
    
    free(arg);

    free(list);
}
int main(int argc, char * argv[])
{
    T_ARG *arg = (T_ARG *)malloc(sizeof(T_ARG));
    
    init(arg);
    
    int ret = -1;
    
    pthread_t threadA, threadB, thread_detect_deadlock, thread_detect_count;
    ret = pthread_create(&threadA, NULL, thread_fun_A, (void *)arg); 
    if(ret != 0)
    {
        printf("Pthread create error!\n");
    }

    ret = pthread_create(&threadB, NULL, thread_fun_B, (void *)arg); 
    if(ret != 0)
    {
        printf("Pthread create error!\n");
    }

    ret = pthread_create(&thread_detect_deadlock, NULL, loop_detect_deadlock_thread, (void *)arg); 
    if(ret != 0)
    {
        printf("Pthread create error!\n");
    }

    ret = pthread_create(&thread_detect_count, NULL, loop_detect_count_thread, (void *)arg); 
    if(ret != 0)
    {
        printf("Pthread create error!\n");
    }
    
    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);

    pthread_cancel(thread_detect_count);
    pthread_cancel(thread_detect_deadlock);
    pthread_join(thread_detect_count, NULL);
    pthread_join(thread_detect_deadlock, NULL);
    
    PLAYER_MUXTEX_DESTROY;

    printf("shareA: %d, shareB: %d\n", arg->shareA, arg->shareB);
    free_player(arg);
}
  1. 有什么不明白的可以留言~看到了就回~  
有什么不明白的可以留言~看到了就回~



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值