多个线程同时访问共享数据可能会冲突。比如两个线程同时把某个全局变量增加1需要3步。
1.从内存读取变量到寄存器
2.把寄存器中变量值加一
3.把结果返回给内存
不同线程的执行时间会造成结果的不同,这时候就需要线程同步:
互斥量(mutex):引入互斥锁,得到锁的线程执行(读,修改,写)的操作,没有获得锁的线程只能等待,不能共享数据。(读,写,修改)的操作就有了原子性(要么执行,要么不执行),不会被打断,避免了线程混乱。
#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); //销毁
条件变量
利用线程间共享的全局变量进行同步的一种机制。条件变量上的基本操作有:触发条件(当条件变为 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); //解除所有线程的阻塞
#include <semaphore.h>
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);
用来释放一个读出或者写入锁