线程同步的几种方式

多个线程同时访问共享数据可能会冲突。比如两个线程同时把某个全局变量增加1需要3步。

1.从内存读取变量到寄存器
2.把寄存器中变量值加一
3.把结果返回给内存
不同线程的执行时间会造成结果的不同,这时候就需要线程同步:

线程同步的四种方式:

  • 互斥量(mutex):引入互斥锁,得到锁的线程执行(读,修改,写)的操作,没有获得锁的线程只能等待,不能共享数据。(读,写,修改)的操作就有了原子性(要么执行,要么不执行),不会被打断,避免了线程混乱。
    #include
    int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);//锁的初始化
    int pthread_mutex_destroy(pthread_mutex_t *mutex); //销毁

  • 条件变量
    利用线程间共享的全局变量进行同步的一种机制。条件变量上的基本操作有:触发条件(当条件变为 true 时);等待条件,挂起线程直到其他线程触发条件。

一个条件变量总是和一个和互斥锁一起使用。

int pthread_cond_init(pthread_cond_t*cond,pthread_condattr_t *cond_attr); //初始化   
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);//线程调用可以在条件变量上阻塞等待(释放mutex, 阻塞等待,获得mutex) 
int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex *mutex,const timespec *abstime);//可以设置等待时间,如果到时还没有被唤醒,就返回
int pthread_cond_destroy(pthread_cond_t *cond); //销毁
int pthread_cond_signal(pthread_cond_t *cond);  //唤醒某个在条件变量上等待的另一个线程
int pthread_cond_broadcast(pthread_cond_t *cond);  //解除所有线程的阻塞
  • 信号量
    信号量的类型是sem_t
#include 
int sem_init (sem_t *sem , int pshared, unsigned int value);  //初始化,value表示可用的资源数,pashared为0时信号量用于同一进程线程间的同步

int sem_wait(sem_t *sem);  //如果资源数大于0,则线程获得资源,资源数减1,如果等于0,线程等待等待不为0为止

int sem_post(sem_t *sem);  //释放资源,资源数+1,同时唤醒等待的线程
int sem_destroy(sem_t *sem);

  • 读写锁
    读写锁是一种特殊的自旋锁。读者写者模型,在编写多线程时有种情况很常见就是共享资源很少修改,但很多人同时访问,比较写,读的机会更多一些。读的过程伴随着查找,比较费时间,给这种代码枷锁,效率很低,就有了读者写者模型。
    可以同时有多个读者只有一个写者。不能同时读和写。
#include 
int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
//在初始化某个读写锁的时候,如果属性指针attr是个空指针的话,表示默认的属性;如果想要使用非默认属性

int pthread_rwlockattr_destroy(pthread_rwlockatttr_t *attr);

int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr);
//用来获取读出锁,如果相应的读出锁已经被某个写入者占有,那么就阻塞调用线程
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr);
//来获取一个写入锁,如果相应的写入锁已经被其它写入者或者一个或多个读出者占有,那么就阻塞该调用线程

int pthread_rwlock_unlock(pthread_rwlock_t *rwptr);
用来释放一个读出或者写入锁

你可能感兴趣的:(Linux,操作系统)