在多线程环境中,线程之间由于竞争共享资源(临界资源)容易引起数据不一致的问题。一般采用互斥锁(互斥信号量)解决,保证只有一个线程进入临界区。
使用步骤:
/**
* 使用宏定义以及初始化锁
*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
/**
* 参数:
* 1:互斥锁
* 2:互斥锁属性
*/
int pthread_mutex_init(pthread_mutex_t * __restrict,
const pthread_mutexattr_t * _Nullable __restrict);
/**
* 参数:
* 互斥锁变量
* 返回值:
* 是否成功
*/
int pthread_mutex_lock(pthread_mutex_t *);
/**
* 参数:
* 互斥锁变量
* 返回值:
* 成功返回0
* 失败返回错误码
*/
int pthread_mutex_trylock(pthread_mutex_t *);
/**
* 参数:
* 互斥锁变量
* 返回值:
* 成功返回0
* 失败返回错误码
*/
int pthread_mutex_lock(pthread_mutex_t *);
/**
* 参数:
* 互斥锁变量
* 返回值:
* 成功返回0
* 失败返回错误码
*/
int pthread_mutex_destroy(pthread_mutex_t *);
为了解决性能问题,引入读写锁,特点是:读共享,写独享,写优先级高,读写之间也是互斥的。适合读线程较多的场景。
注意:在A线程加锁状态下,当B线程请求读锁,然后C线程请求写锁时,在A释放锁的情况下,C请求的写锁先获取到。
读写锁使用步骤与互斥锁基本相同,函数原型如下。
//初始化
pthread_rwlock_t mutex = PTHREAD_RWLOCK_INITIALIZER;
//或者
int pthread_rwlock_init(pthread_rwlock_t * __restrict,
const pthread_rwlockattr_t * _Nullable __restrict);
//加锁(读写)
int pthread_rwlock_rdlock(pthread_rwlock_t *);
int pthread_rwlock_tryrdlock(pthread_rwlock_t *)
int pthread_rwlock_wrlock(pthread_rwlock_t *);
int pthread_rwlock_trywrlock(pthread_rwlock_t *);
//解锁
pthread_rwlock_unlock();
//释放锁
int pthread_rwlock_destroy(pthread_rwlock_t * )
条件变量本质不是锁,通常与互斥锁配合使用。
当条件不满足时,阻塞线程。
当条件满足时,通知线程解除阻塞。
区别于Java:
1. Object中wait()、notify()、notifyAll() 是进程间通信(同步)的方式,且必须在synchronized中使用。
2. Java并发包下condition.await()、condition.signal() 也是用于线程通信的。
使用方式:
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
//或者
int pthread_cond_init(
pthread_cond_t * __restrict,
const pthread_condattr_t * _Nullable __restrict)
/**
* 阻塞并且释放锁
* 当接收到信号加锁继续执行
*
* 参数:
* 1:条件变量
* 2:锁
* 返回值:
* 是否成功
*/
int pthread_cond_wait(pthread_cond_t * __restrict,
pthread_mutex_t * __restrict)
/**
* 唤醒阻塞的线程
* 参数:
* 条件变量
* 返回值:
* 是否成功
*/
int pthread_cond_signal(pthread_cond_t *)
int pthread_cond_destroy(pthread_cond_t *);
信号量是用来标识可同时使用的共享资源的个数。
使用方式:
/**
* 参数:
* 1:sem_t变量
* 2:0线程同步,1进程同步
* 3:资源数
* 返回值:
* 是否成功
*/
int sem_init(sem_t *, int, unsigned int)
int sem_wait(sem_t *)
int sem_trywait(sem_t *)
int sem_post(sem_t *)
int sem_destroy(sem_t *)