zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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线程
    ");
            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("退出后的调用!
    ");
            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
    ",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
    ",i);
                    usleep(100);
                    pthread_mutex_unlock(&m);
            }
    }
  • 相关阅读:
    安装MySQLdb
    树莓派及其他硬件平台国内外Linux镜像站全汇总
    rpc使用举例
    SAE上安装第三方模块
    【Java】Map
    【Java】判断字符串是否含字母
    【Android Studio】提示代码忽略大小写
    【iOS】Xcode 离线文档
    【iOS】iOS main() 简介
    【eclipse】No enclosing instance of type A is accessible. Must qualify the allocation with an enclosing instance of type A
  • 原文地址:https://www.cnblogs.com/huacw/p/3601078.html
Copyright © 2011-2022 走看看