线程安全--互斥锁实现,互斥锁相关知识,死锁

**

线程安全–互斥锁实现

线程安全的概念
多个线程对临界资源的合理性访问。
临界资源:多个执行流 共享的资源叫做临界资源
临界区:每个线程内部,处理临界资源的代码,就叫做临界区。
如何实现线程安全:同步(不保证安全)与互斥(不保证合理)
同步实现:使多个线程在某种规则条件下,实现在资源共同访问的合理性。使用条件变量和信号量实现
互斥实现:在某一个时间,只有一个线程可以访问资源,实现访问的安全性。使用互斥许锁和信号量实现

互斥实现线程安全的原理
线程安全--互斥锁实现,互斥锁相关知识,死锁_第1张图片
黄牛抢票的例子
有100张票,需要被抢,他就是临界资源。创建4个线程一块去抢,相当于多线程。这个时候,可能出现一个黄牛抢了所有的票,并且在票为负时,黄牛还能抢票。
为什么出现这种结果
1、在我们判断临界资源还有的时候,这个时候代码并发切换到其他线程。其他线程刚好访问了最后的资源,然后切换至这个线程,导致没有资源,但是这个线程还访问了。
2、对于资源的–可能不是一个原子操作,中间会被打断。(原子操作:不会被任何的调度机制打断,要么全部完成,要么不完成)

**所以为了实现线程的安全,可以考虑一个互斥锁mutex,根据上图的原理,在执行临界区时先加上锁,离开临界区时解锁
如何加锁
1、代码要有互斥能力,当有一个线程执行到临界区,则阻止其他线程进入临界区。
2、当没有线程在临界区,多个线程要求同时执行临界区,只能一个线程进入临界区。
3、如果某线程不在临界区,是不能够阻止其他线程进临界区。

互斥锁:互斥锁本身就是一个0/1的计数器,它用来标志着临界资源是否可以被访问的状态。当线程要去访问临界资源的时候,必须先去访问互斥锁,看是否可以访问临界资源。
可以访问将访问状态置为不可访问,再进入临界区进行资源访问,当访问完临界资源之后,一定要将临界资源的状态转换为可访问状态;
不可以访问,则阻塞或者报错。

关于互斥锁mutex所有函数操作
1、定义互斥锁变量
pthread_mutex_t mutex;
2、初始化互斥锁变量
互斥锁静态分配–不需要销毁
pthread_mutex_t mutex = PTHREAD_ MUTEX_ INITIALIZER ;
互斥锁动态分配–需要销毁
pthread_mutex_init(pthread_mutex_t *mutex,pthread_mutex_t *attr)
pthread_mutex_init(&mutex,NULL); 创建线程之前对锁进行初始化
3、访问临界资源(执行临界区)之前进行加锁操作。因为不知道临界资源现在的访问状态是什么,所以加锁是一个尝试的过程。
pthread_mutex_lock(pthread_mutex_t *mutex) --加不上锁阻塞等待,然后等着可访问临界资源状态的时候。
pthread_mutex_trylock(pthread_mutex_t *mutex) --加不上锁则报错返回EBUSY。;
pthread_mutex_lock(&mutex);–加锁一定是访问临界资源之前一步
4、临界资源访问完成后进行解锁操作(将临界资源的访问状态定义为可访问状态,唤醒其他线程)
pthread_mutex_unlock(pthread_mutex_t * mutex);
pthread_mutex_unlock(&mutex

你可能感兴趣的:(linux)