线程——锁

一.同步,竞争,互斥
当多个线程同时访问其共享资源时,需要相互协调,以防止出现数据不一致,不完整问题,能达到这种状态叫线程同步
而有些资源在同一时刻只有一个线程访问,对于这种资源的访问需要竞争
当资源获取到后,能够防止资源被其他线程再次获取的方法叫互斥
二.互斥量(锁)

 	pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER
 	int pthread_mutex_init(pthread_mutex_t *_mutex,_const pthread_mutexattr_t* _mutexattr)
 	功能:初始化互斥量,使用第二互斥量来初始化第一个互斥量,如果第二个为空,则使用默认参数初始化互斥量,也可以使用宏来初始化
 	
 	int pthread_mutex_destory(pthread_mutex_t *_mutex)
 	功能:销毁互斥量
 	注意:互斥量是一个结构体,里面有成员是指针,指向了堆内存数据,需要显式初始化函数以及销毁函数
 		如果使用堆内存存储互斥量,需要在调用完函数以后进行free
 		
 	int pthread_mutex_trylock(pthread_mutex_t *_mutex)
 	功能:尝试锁定互斥量,能锁就锁,不能锁则返回
 	
 	int pthread_mutex_lock(pthread_mutex_t *_mutex)
 	功能:锁定互斥量,当互斥量是锁定状态,此函数阻塞(直到互斥量在其他线程中解锁,调用者线程加锁成功才返回)
 	注意:互斥量一旦加锁,只有它自己能解
 	
 	int pthread_mutex_timedlock(pthread_mutex_t *_restrict _mutex,const struct timespec *_restrict_abstime);
 	功能:在指定时间内锁定一个互斥量(由于系统原因导致不可知锁的状态),而一旦获取锁的状态后立即做抉择
 	       struct timespec{
 	       		_time_t  tv_sec;			//Seconds
 	       		long int tv_nsec;			//Nanoseconds
 	       };
 	
 	int pthread_mutex_unlock (pthread_mutex_t *__mutex);
 	功能:解锁

三.死锁
什么是死锁:多个线程进行等待对方的资源,在得到所有资源继续运行前,都不会释放自己的资源,这样造成的循环等待现象,称为死锁
构成死锁的四大必要条件
1.资源互斥
2.占有,还想占有(请求并保留)
3.资源不可剥夺
4.环路等待(互相等待)

防止死锁的方法:
构成死锁的四大条件只要破坏其中一个就构不成死锁,死锁一旦形成就无法消除,因此最好的方法就是避免产生死锁
1.破坏互斥条件,让资源能够共享,但缺点就是不通用,因为有些资源不能共享,如打印机
2.破坏请求并保持条件采用预先分配的方法,在进行运行前一次申请好它所需要的所有资源,但缺点是浪费资源
3.破坏不可剥夺的条件,对已经占用资源的线程发送取消请求,但实现比较复杂,而且还会破坏业务逻辑。
4.破坏循环等待条件,为每个资源进行编号,采用顺序的资源分配方法,规定每个线程必须按照递增的顺序请求资源, 缺点是编号必须相对稳定,增加新资源时会比较麻烦,而且有些特殊的业务逻辑不能完全按照指定的顺序分配资源

避免产生死锁的算法(银行家算法)
1.贷款的额度不能超过现有资源的总和
2.分批向银行贷款,但是贷款的额度不能超过一开始最大需求量总和
3.银行如果不能满足客户的需要,必须要及时给出答复
4.客户必须在规定时间内还款
如何检测死锁:
1.画出资源分配图,并简化,模拟资源分配的流程
2.监控线程过程的栈内存使用情况
3.设计看门狗机制(TCP心跳包)
四.信号量

		线程的信号量与进程的信号量的机制是一样的,但使用方法不同,用于控制,管理线程间的共享资源
		#include <semaphore.h>
		int sem_init(sem_t *sem, int pshared, unsigned int value);
		功能:初始化信号量(创建信号量)
		sem:信号量ID,输出
		pshared:一般为0(线程之间)进程中使用
				非零表示进程间使用,但Linux不支持
		value:信号量的初值
		int sem_wait(sem_t *sem);
		功能:信号量减1,不够减则阻塞(0)
		
        int sem_trywait(sem_t *sem);
		功能:信号量减1,不够减立即返回-1

        int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);		
		功能:信号量减1,不够减则阻塞,直到abs_timeout超时返回-1
		int sem_post(sem_t *sem);
		功能:信号量加1
		
		int sem_destroy(sem_t *sem);
		功能:销毁信号量
		int sem_getvalue(sem_t *sem, int *sval);
		功能:获取信号量的值

五.条件变量

		条件变量可以让线程在满足特定的条件下暂停(睡眠),要与互斥量配合使用
		pthread_cond_t cond=PTHREAD_COND_INITIALIZER
		extern int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t * cond_attr);
		功能:初始化条件变量
		cond:待初始化的条件变量
		cond_attr:条件变量的属性
		
		int pthread_cond_destroy(pthread_cond_t *cond);
		功能:销毁条件变量
		
		int pthread_cond_signal(pthread_cond_t *cond);
		功能:唤醒条件变量中的线程
		注意:线程醒的前提条件是互斥量必须是解锁状态的,线程醒前会再次加锁,如果不能加锁就不会醒来
		
		extern int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *_mutex);
		功能:让调用者线程进入睡眠,并解锁一个互斥量
		cond:线程睡眠的条件变量
		mutex:线程睡眠前的要解锁的互斥量(是不是锁定状态没有关系)
		返回值:成功返回0,失败返回-1
		
		int pthread_cond_timewait(pthread_cond_t *cond,pthread_mutex_t *_mutex, struct timespec abstime)
		功能:让调用者线程进入睡眠(指定睡眠时间),并解锁一个互斥量
		注意:使用的是系统时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值