Linux系统基础(线程管理)

一、同步、竞争、互斥

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

二、互斥量(锁)

pthread_mutex_t mutex =PTHREAD_MUTEX_INITALIZER

int pthread_mutex_init (pthread_mutex_t *__mutex,
__const pthread_mutexattr_t *__mutexattr)
__THROW __nonnull ((1));
功能:初始化互斥量,使用第二个互斥量来初始化第一个互斥量,如果第二个为空
则使用默认参数初始化互斥量,也可以使用宏来初始化

int pthread_mutex_destroy (pthread_mutex_t *__mutex)
功能:销毁互斥锁

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)
功能:在指定的时间内锁定互斥量(由于系统原因不可知锁的状态,一旦获取锁的状态以后立即做出抉择)

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(线程之间)进程中使用的
非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);
功能:获取信号量的值

五、生产者与消费者模型

在这里插入图片描述

六、条件变量

条件变量可以让线程在满足特定的条件下暂停(睡眠),需要与互斥量配合使用
int pthread_cond_init (pthread_cond_t *cond,
__const pthread_condattr_t *cond_attr)
功能:初始化条件变量
cond:初始化条件变量
cond_attr:初始化条件变量的属性
int pthread_cond_destroy (pthread_cond_t *__cond)
功能:销毁条件变量
int pthread_cond_signal (pthread_cond_t *__cond)
功能:唤醒条件变量中的线程
线程醒的前提条件是互斥量必须是解锁状态
线程醒的一瞬间会再次加锁如果不能加锁就不会醒来
int pthread_cond_wait (pthread_cond_t *cond,
pthread_mutex_t *mutex)
功能:调用者线程进入睡眠,并解锁一个互斥量
cond:让线程睡入的条件变量
mutex:线程睡眠前要解锁的互斥量
int pthread_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mutex,__const struct timespec *__restrict
__abstime)
功能:让调用者线程进入睡眠,并解锁一个互斥量(是不是锁定状态没有关系)
注意:使用的是系统时间。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值