• 线程同步之互斥量


    互斥量:

    当多个线程共享相同的内存时,需要每一个线程看到相同的视图。当一个线程修改变量时,而其他线程也可以读取或者修改这个变量,就需要对这些线程同步,确保他们不会访问到无效的变量

    在变量修改时间多于一个存储器访问周期的处理器结构中,当存储器的读和写这两个周期交叉时,这种潜在的不一致性就会出现。当然这与处理器相关,但是在可移植的程序中并不能对处理器做出任何假设

    为了让线程访问数据不产生冲突,这要就需要对变量加锁,使得同一时刻只有一个线程可以访问变量。互斥量本质就是锁,访问共享资源前对互斥量加锁,访问完成后解锁
    当互斥量加锁以后,其他所有需要访问该互斥量的线程都将阻塞
    当互斥量解锁以后,所有因为这个互斥量阻塞的线程都将变为就绪态,第一个获得cpu的线程会获得互斥量,变为运行态,而其他线程会继续变为阻塞,在这种方式下访问互斥量每次只有一个线程能向前执行


    互斥量用pthread_mutex_t类型的数据表示,在使用之前需要对互斥量初始化
    1、如果是动态分配的互斥量,可以调用pthread_mutex_init()函数初始化
    2、如果是静态分配的互斥量,还可以把它置为常量PTHREAD_MUTEX_INITIALIZER
    3、动态分配的互斥量在释放内存之前需要调用pthread_mutex_destroy()


    int pthread_mutex_init(pthread_mutex_t *restrict mutex,
              const pthread_mutexattr_t *restrict attr);


    int pthread_mutex_destroy(pthread_mutex_t *mutex);
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

    加锁 
         int pthread_mutex_lock(pthread_mutex_t *mutex); 
        成功返回0,失败返回错误码。如果互斥量已经被锁住,那么会导致该线程阻塞
          int pthread_mutex_trylock(pthread_mutex_t *mutex);
        成功返回0,失败返回错误码。如果互斥量已经被锁住,不会导致线程阻塞


    解锁  
        int pthread_mutex_unlock(pthread_mutex_t *mutex);
        成功返回0,失败返回错误码。如果一个互斥量没有被锁住,那么解锁就会出错

    死锁:线程一直在等待锁,而锁却无法解开


    如果一个线程对已经占有的互斥量继续加锁,那么他就会陷入死锁状态。
       lock mutex--------lock mutex--------阻塞
       解除阻塞状态的条件:mutex unlock
       mutex unlock的条件:  解除阻塞态


    程序中使用多个互斥量时,如果一个线程一直占有互斥量A,并且试图加锁互斥量B,但是拥有互斥量B的线程却要加锁互斥量A,这时就会出现死锁
        线程1: lock A成功
        线程2 : lock B成功 
        线程1: lock B失败, 阻塞
        线程2: lock A失败, 阻塞
        线程1解除阻塞的条件:线程2将B解锁
        线程2解除阻塞的条件:线程1将A解锁


    如何去避免
    你可以小心的控制互斥量加锁的顺序来避免死锁,例如所有的线程都在加锁B之前先加锁A,那么这两个互斥量就不会产生死锁了

  • 相关阅读:
    win10和Ubuntu双系统安装过程中遇到的问题
    python中矩阵的用法
    python中yield的用法
    python中的*和**的用途
    python函数后面有多个括号怎么理解?
    keras中的重要函数
    机器学习的常见算法
    agent page
    Spring常用注解介绍【经典总结】
    Spring配置中<context:annotation-config> VS <context:component-scan>
  • 原文地址:https://www.cnblogs.com/CHYI1/p/5445690.html
Copyright © 2020-2023  润新知