互斥锁,信号量,条件变量,读写锁

互斥锁

互斥锁的特性:

1. 原子性:当有一个线程成功拿到了这个锁,其他线程都无法在相同的时间拿到这个锁

2. 唯一性:在一个线程拿到锁的这段时间,只有当这个线程把锁释放掉,其他的线程才有可能拿到

3. 非繁忙等待性:如果一个线程已经锁定了一个互斥量,第二个线程又视图去拿到这个锁的前线,则第二个锁将被挂起,等待第一个线程对互斥量解锁位置,同时第二个线程获取锁,继续往下执行

pthread_mutex_init
pthread_mutex_lock
pthread_mutex_trylock
pthread_mutex_unlock
pthread_mutex_destroy

 

信号量

信号量相当于一个加强版的互斥锁,提高了共同访问共享资源的线程数目(从串行,变成了并行)

sem_init
sem_wait
sem_trywait
sem_post
sem_getvalue
sem_destroy

 

条件变量

自动阻塞一个线程,直到某种特殊的情况发生为止,通常条件变量和互斥锁相互配合使用。

条件变量使得我们可以睡眠等待某种条件出现,条件变量是利用线程间共享的全局变量进行同步的一个机制。

条件变量主要包括两个动作:

1. 一个线程等待 “条件变量的成立“ 

2. 另一个线程使得 “条件成立”

条件变量的作用:

1. 先把调用线程放到等待条件的队列上 

2. 释放指定的锁以提供其他线程添加任务

3. 等待任务添加完毕

4. 在函数调用返回的时候把mutex锁住

具体理解

就是两个线程需要进行碰头,在条件变量这个地方发生,一个线程修改变量使得它满足其他线程继续往下执行的条件,其他线程则接受条件已经发生改变的信号。可以实现无竞争,就是信号可以被所有等待这个信号的进程接受

条件的检测是在互斥锁的保护下进行的,线程在改变条件之前必须先拿到锁的权限。当条件成立的时候,会发送给关联的条件变量

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t * mutex);

mutex的作用是保护条件变量,调用这个函数的时候,mutex会自动释放,等待其他线程发出cond这个信号。

这两个步骤必须是原子性的,如果 释放mutex的时候,别的线程发出了信号,然后这个时候还没有把调用线程放到等待队列上,这个signal信号就会丢失。

为什么需要加锁。并且将这两部分合成原子操作?

如果不加锁的话,当我们先释放mutex的时候,到signal还有一段距离,如果这一段我们发出了signal,处理者线程是有很大可能无法收到signal的。比如等到singal发出来的时候,调用线程还没到等待队列上,而这个时候signal可能已经被其他线程接受了

为什么要先释放锁,然后等待信号发过来?

结合线程池的设计思路,如果不释放锁的话,这个信号有很大可能是发送不过来的,其他的线程可能根本没有机会发出信号。

 

读写锁

遵循读时共享,写时独占

 

posted @ 2019-10-15 20:35  Let_Life_Stop  阅读(414)  评论(0编辑  收藏  举报