Linux 多线程互斥量同步

同步

同一个进程中的多个线程共享所在进程的内存资源,当多个线程在同一时刻同时访问同一种共享资源时,需要相互协调,以避免出现数据的不一致和覆盖等问题,线程之间的协调和通信的就叫做线程的同步问题, 线程同步的思路: 让多个线程依次访问共享资源,而不是并行

互斥VS同步

  • 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
  • 同步:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源

互斥量Mutex:

  • 本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。互斥量使同时只能有一个进程访问数据,可以看做一种的0/1信号量
  • Mutex对象的值只有0和1。分别代表了Mutex的锁定状态和空闲状态:
    • 锁定状态:当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入等待;
    • 空闲状态:当前对象为空闲,用户进程/线程可以Lock临界资源,之后Mutex值减1变为0。
  • Mutex被创建时可以有初始值,表示Mutex被创建后,是锁定状态还是空闲状态。
  • 在同一个线程中,为了防止死锁,系统不允许连续两次对Mutex加锁(系统一般会在第二次调用立刻返回)。也就是说,加锁和解锁这两个对应的操作,需要在同一个线程中完成。

互斥量模型

  1. 定义互斥锁: pthread_t mutex
  2. 初始化锁: pthread_mutex_init()
  3. 加锁: pthread_mutex_lock()/pthread_mutex_trylock()
  4. 解锁: pthread_mutex_unlock()
  5. 销毁: pthread_mutex_destroy()
//成功返回0,失败返回error number
#include <pthread.h>
int pthread_mutex_init  (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock  (pthread_mutex_t *mutex);
int pthread_mutex_trylock   (pthread_mutex_t *mutex);
int pthread_mutex_unlock    (pthread_mutex_t *mutex);
int pthread_mutex_destroy   (pthread_mutex_t *mutex);

死锁(deadlock)

主要发生在有多个依赖锁存在时, 会在一个线程试图以与另一个线程相反顺序锁住互斥量时发生:
A试图按照AB的方向使用共享资源,B试图按照BA的方向使用共享资源,不巧的是,此时锁定A资源等待B资源被释放, 也在锁定B资源等待A资源被释放, 二者将要使用的资源都被对方锁着, 形成了死锁。
为避免死锁, 有几个不成文的基本原则:

  1. 对共享资源操作前一定要获得锁。
  • 完成操作以后一定要释放锁。
  • 尽量短时间地占用锁。
  • 如果有多锁, 如获得顺序是ABC连环扣, 释放顺序也应该是ABC。
  • 线程错误返回时应该释放它所获得的锁。

猜你喜欢

转载自www.linuxidc.com/Linux/2016-10/135941.htm