1、线程互斥
临界资源:多线程执行流共享的资源就叫做临界资源
临界区:每个线程内部,访问临界资源的代码,就叫做临界区
互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起到保护作用
原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成
ticket是一个全局变量,是一个临界资源
多线程切换的情况下(OS中什么时候可能进行线程间切换呢?从内核态返回用户态),极有可能因为数据交叉操作,而导致数据不一致的问题,
要解决上述问题需要做到三点:
1、代码需要有互斥行为:当代码进入临界区执行时,不允许其他线程进入该临界区
2、如果多个线程要求执行临界区的代码,并且临界区没有线程在执行,那么只能允许一个线程进入该临界区
3、如果线程不在临界区中执行,那么该线程不能阻止其他线程进入该临界区。
互斥量实现原理:
这里使用的xchgb是从物理层面保证交换的原子性
可重入和线程安全
线程安全:多个线程并发同一段代码时不会出现不同的结果。常见对全局变量或者静态变量进行操作,并且没有锁保护的情况下,会出现该问题
重入:同一个函数被不同的执行流调用,当前一个流程还没有执行完,就有其他执行流再次进入,我们称为重入。一个函数在重入的情况下,运行结果不会出现任何不同或者任何问题,则该函数称为可重入函数,否则,是不可重入函数
线程同步
什么是同步:
在保证数据安全的情况下,让多个执行流按照特定的顺序进行临界资源的访问,从而有效避免饥饿问题称为同步
为什么要存在同步?多线程协同高效完成某些事情
为什么pthread_cond_wait需要互斥量?
通常的应用场景下,当前线程执行pthread_cond_wait时,处于临界区访问共享资源,存在一个mutex与该临界区相关联
当线程执行pthread_cond_wait前,已经获得了和临界区相关联的mutex,执行pthread_cond_wait时阻塞,但是为了让其他线程能够进入临界区,必须在进入阻塞状态前,释放已经获得的mutex,让其他线程能够进入该临界区
当前线程执行pthtread_cond_wait时,阻塞等待的条件满足,会被唤醒;唤醒后,任然处于临界区,因此唤醒后必须再次获得和临界区相关联的mutex