• 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);
            }
    }
  • 相关阅读:
    Dispatcher及线程操作
    MVVM中轻松实现Command绑定(三)任意事件的Command
    MVVM Light中的Message
    Prism
    Prism的IEventAggregator事件聚合器, 事件订阅发布, ViewModel之间的通讯
    文件写操作--WriteLog
    【Golang】Debug :decoding dwarf section info at offset 0x0: too short
    【Golang 接口自动化03】 解析接口返回XML
    【Golang 接口自动化02】使用标准库net/http发送Post请求
    【Golang 接口自动化01】使用标准库net/http发送Get请求
  • 原文地址:https://www.cnblogs.com/huacw/p/3601078.html
Copyright © 2020-2023  润新知