1、互斥量(互斥锁)
#include<pthread.h>
// 初始化互斥量
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
// 销毁互斥量
int pthread_mutex_destroy(pthread_mutex_t *mutex);
// 加锁(线程可能会阻塞)
int pthread_mutex_lock(pthread_mutex_t *mutex);
// 尝试加锁(线程不会被阻塞)
int pthread_mutex_trylock(pthread_mutex_t *mutex);
// 解锁
int pthread_mutex_unlock(pthread_mutex_t *mutex);
2、读写锁(共享互斥锁)
读写锁可以有三种状态:读模式下加锁、写模式加锁、不加锁状态。一次可以只有一个线程占有读写锁的写模式,但是多个线程可以同时占用读模式的读写锁。当读写锁是写加锁状态时,在这个锁解锁之前,所有试图对这个锁加锁的线程都会被阻塞。当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是任何希望以写模式对此锁进行加锁的线程都会阻塞,直到所有的线程释放他们的写锁为止。读写锁适用于对数据的读远大于写的情况。
#include <pthread.h>
// 初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
// 销毁读写锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
// 读模式加锁(阻塞模式)
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
// 读模式加锁(非阻塞模式)
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
// 写模式加锁(阻塞模式)
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
// 写模式加锁(非阻塞模式)
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
// 解锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
3、自旋锁
自旋锁和互斥量类似,忙等(自旋)阻塞,而不是休眠阻塞。自旋锁适用于持有的时间端,而且线程并不希望在重新调度上花费太多的成本。多用于内核态,用户态用的比较少。
#include <pthread.h>
// 初始化自旋锁
int pthread_spin_init(pthread_spinlock_t *lock);
// 销毁自旋锁
int pthread_spin_destroy(pthread_spinlock_t *lock);
// 加锁(阻塞模式)
int pthread_spin_lock(pthread_spinlock_t *lock);
// 加锁(非阻塞模式)
int pthread_spin_trylock(pthread_spinlock_t *lock);
// 解锁
int pthread_spin_unlock(pthread_spinlock_t *lock);
4、条件变量
条件变量是线程可用的另外一个同步机制,条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定条件的发生,主要用于线程池之中。条件本身是由互斥量保护的,线程在改变条件之前必须首先锁住互斥量。
注意:针对pthread_cond_wait()这个函数,调用者把锁住的互斥量传给函数,函数自动把调用线程放到等待条件发生的线程列表上,对互斥量解锁。当pthread_cond_wait()返回时,互斥量将再次被锁住。
#include <pthread.h>
// 初始化条件变量
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
// 销毁条件便来给你
int pthread_cond_destroy(pthread_cond_t cond);
// 等待条件发生(调用者把锁住的互斥量传递给函数,函数把调用线程放在等待条件的线程列表上,对互斥来给你解锁)
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);
// 超时指定我们愿意等待多长时间
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);
// 触发等待在该条件上的某一个线程
int pthread_cond_signal(pthread_cond_t cond);
// 触发等待在该条件上的所有线程
int pthread_cond_broadcast(pthread_cond_t cond);
5、屏障
屏障是用于协调多个进程并行工作的同步机制,屏障允许每个线程等待,直到所有合作线程都到达某个点后,然后从该点继续执行。
#include<pthread.h>
// 屏障初始化
int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_ty * restrict attr, unsigned int count);
// 屏障销毁
int pthread_barrier_destroy(pthread_barrier_t *barrier);
// 线程阻塞到屏障,如果是调用该函数的最后一个线程满足屏障计数,则所有的线程都被唤醒
int pthread_barrier_wait(pthread_barrier_t *barrier);