zoukankan      html  css  js  c++  java
  • 第9章 线程编程(8)_死锁

    5.6 死锁

    (1)死锁:两个线程试图同时占用两个资源,并按不同的次序锁定相应的共享资源。

    (2)解决方案:

      ①方案1:按相同的次序锁定相应的共享资源

      ②方案2:使用pthread_mutex_trylock(),它是pthread_mutex_lock()函数的非阻塞版。

    【编程实验】死锁

    //dead_lock.c

    #include <pthread.h>
    #include <errno.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct
    {
        int value;
        pthread_mutex_t mutex;
    }ResourceA;
    
    typedef struct
    {
        int value;
        pthread_mutex_t mutex;
    }ResourceB;
    
    typedef struct
    {
        ResourceA*   ra;
        ResourceB*    rb;
    }Storage;
    
    void* a_fn(void* arg)
    {
        Storage* s = (Storage*)arg;
    
        //先对ResourceA加锁
        pthread_mutex_lock(&s->ra->mutex);
        sleep(1);
        
        printf("0x%lx is waiting for ResourceB...
    ", pthread_self());
        //再次ResourceB加锁
        pthread_mutex_lock(&s->rb->mutex);
        printf("ResourceA value is:%d
    ", s->ra->value);
        printf("ResourceB value is:%d
    ", s->rb->value);
        
        pthread_mutex_unlock(&s->rb->mutex);
        pthread_mutex_unlock(&s->ra->mutex);
    
        return (void*)0;
    }
    
    void* b_fn(void* arg)
    {
       /*死锁
        Storage* s = (Storage*)arg;
    
        //先对ResourceB加锁
        pthread_mutex_lock(&s->rb->mutex);
        sleep(1);
        
        printf("0x%lx is waiting for ResourceA...
    ", pthread_self());
        //再次ResourceA加锁
        pthread_mutex_lock(&s->ra->mutex);
        printf("ResourceA value is:%d
    ", s->ra->value);
        printf("ResourceB value is:%d
    ", s->rb->value);
        
        pthread_mutex_unlock(&s->ra->mutex);
        pthread_mutex_unlock(&s->rb->mutex);
        */
    
        //解决方案:与a线程一样,按相同的次序加锁
        Storage* s = (Storage*)arg;
    
        //先对ResourceA加锁
        pthread_mutex_lock(&s->ra->mutex);
        sleep(1);
        
        printf("0x%lx is waiting for ResourceB...
    ", pthread_self());
        //再次ResourceB加锁
        pthread_mutex_lock(&s->rb->mutex);
        printf("ResourceA value is:%d
    ", s->ra->value);
        printf("ResourceB value is:%d
    ", s->rb->value);
        
        pthread_mutex_unlock(&s->rb->mutex);
        pthread_mutex_unlock(&s->ra->mutex);
    
    
        return (void*)0;
    }
    
    int main(void)
    {
        ResourceA  ra;
        ResourceB  rb;
        ra.value = 100;
        rb.value = 200;
        pthread_mutex_init(&ra.mutex, NULL);
        pthread_mutex_init(&rb.mutex, NULL);
        Storage s = {&ra, &rb};
    
        int err = 0;
        pthread_t   thread_a, thread_b;
        if((err = pthread_create(&thread_a, NULL, a_fn, (void*)&s)) !=0){
            fprintf(stderr, "pthread_create:%s
    ", strerror(errno));
            exit(1);
        }
        if((err = pthread_create(&thread_b, NULL, b_fn, (void*)&s)) !=0){
            fprintf(stderr, "pthread_create:%s
    ", strerror(errno));
            exit(1);
        }
    
        pthread_join(thread_a, NULL);
        pthread_join(thread_b, NULL);
    
        pthread_mutex_destroy(&ra.mutex);
        pthread_mutex_destroy(&rb.mutex);
    
        return 0;
    }
    /*
     0xb6d08b70 is waiting for ResourceB...
     ResourceA value is:100
     ResourceB value is:200    //死锁时,停在这个位置
     0xb7709b70 is waiting for ResourceB...
     ResourceA value is:100
     ResourceB value is:200    //未发生死锁时会输出到这里
     */
  • 相关阅读:
    pymysql
    Mysql
    协程
    线程池
    线程 条件
    线程 事件
    线程
    requests
    Linux 时区不对的解决办法
    Linux 简单命令
  • 原文地址:https://www.cnblogs.com/5iedu/p/6426996.html
Copyright © 2011-2022 走看看