多线程多并发情况下的互斥有哪些方法

多线程并发之间有多种锁的模式,适应于不同的应用场景。锁的模式有些地方也叫线程之间的同步方式。所谓的同步就是多个线程之间进行数据一致性需要用到的机制。

一、互斥锁mutex(pthread_mutex_t)
pthread_mutex_t,读写都独占的模式。最常用的模式,也就是编码中最喜欢用的。。。。
1.1、一旦一个线程拿到锁,另一个线程需要阻塞等待前一个线程释放锁才能拿到这个锁。
1.2、为了不让线程阻塞,则可以调用trylock的接口,通过返回值来判断是否加锁成功。
1.3、但是这个锁有个问题就是线程之间不能并发,只能串行进行,为此系统又提供了一个可以支持读并发的锁。pthread_rwlock_t 读写锁

1、pthread_mutex_t lock;
2、pthread_mutex_init(&lock)
3、pthread_mutex_lock(&lock);
4、pthread_mutext_unlock(&lock);

二、读写锁(pthread_rwlock_t)
在读的模式下,可以多个线程同时获取到锁,以至于可以做到多个读线程并发的目的,但是对于写操作,还是串行的。同时读和写之间也只能互斥。同时如果一旦这个读写锁已经被线程A锁住,后后面因为另一个线程B需要加写锁,那么需要阻塞等待,此时在一个线程C需要加读锁,此时也会组撒,但是一旦A释放锁,那么线程B的占用的锁的优先级会更高,因为写锁的优先级比读锁的优先级高。

1、pthread_rwlock_t lock;
2、pthread_rwlock_init(&lock)
3、pthread_rdlock(&lock);
4、pthread_wrlock(&lock);

三、条件变量(pthread_cond_t)
前面说的互斥量和读写锁,只能保证多个线程互斥访问共享资源,但是不能阻塞等待某个条件满足后继续执行线程的动作。比如这样的场景:一个线程需要从一个链表中取数据来处理,但是这个链表在某些时候为空,那么则这个线程需要等待(pthread_cond_wait)这个链表有数据后,在继续执行。这歌场景在mutex和读写锁锁是搞不定的,因此这样的场景就需要条件变量来解决。条件变量不是锁,不会锁共享资源但是可以组赛线程等到某个条件满足后,继续执行。这就是条件变量的原理。

1、pthread_cond_t cond;
2、pthread_cond_init(&cond);
3、pthread_cond_wait(&cond);
4、pthread_cond_signal(&cond);通知

条件变量不是锁,只是阻塞线程的作用,要做到锁的效果,需要结合互斥锁。

四、信号量(sem_t sem)
互斥锁只能保证线程间串行处理,不能并行处理,要并行的话则需要使用读写锁。但是读写锁适用于了读多写少的场景。因此在Linux中有一种机制信号量可以让多个线程并行访问共享资源。当然信号量是锁(sem_t sem).其实信号量主要是处理多并发限制的场景,也就是并发数量不能超过多少的场景。

注意信号量也可以作为进程间同步的方式;此时sem_init(&sem, share, 100)中share=1表示进程间同步

1、sem_t sem;
2、sem_init(&sem, 0, 100)//初始化并发数目 100(value),也就是可以支持100个线程进程共享访问共享资源。
3、sem_wait(&sem);调用一次wait就相当于对value值减1
4、sem_post(&sem);调用一次pst相当于对value++;

使用信号量做生产者和消费者模型
在这里插入图片描述

总结:其实信号量就是对value值进行操作,而mutex值其实就是value=2的信号量。这样只能做到两个线程之间互斥。而条件变量则是阻塞线程,不启互斥作用。读写锁是处理读多写少的场景,起到读写互斥,读读并发不互斥的作用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章