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);
            }
    }
  • 相关阅读:
    MapReduce学习总结之简介
    Hive Cli相关操作
    使用Hive UDF和GeoIP库为Hive加入IP识别功能
    Google Maps-IP地址的可视化查询
    hive多表联合查询(GroupLens->Users,Movies,Ratings表)
    云计算平台管理的三大利器Nagios、Ganglia和Splunk
    机器大数据也离不开Hadoop
    hive与hbase的整合
    hive优化之------控制hive任务中的map数和reduce数
    Hadoop管理员的十个最佳实践(转)
  • 原文地址:https://www.cnblogs.com/huacw/p/3601078.html
Copyright © 2011-2022 走看看