互斥锁
互斥锁的特性:
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可能已经被其他线程接受了
为什么要先释放锁,然后等待信号发过来?
结合线程池的设计思路,如果不释放锁的话,这个信号有很大可能是发送不过来的,其他的线程可能根本没有机会发出信号。
读写锁
遵循读时共享,写时独占
原文地址:https://www.cnblogs.com/letlifestop/p/11680278.html