您的位置:首页 > 汽车 > 新车 > 河北省建设工程招标网_安徽阜阳疫情最新消息_html网站模板免费_semaphore

河北省建设工程招标网_安徽阜阳疫情最新消息_html网站模板免费_semaphore

2025/1/14 10:13:22 来源:https://blog.csdn.net/2301_77329667/article/details/143184361  浏览:    关键词:河北省建设工程招标网_安徽阜阳疫情最新消息_html网站模板免费_semaphore
河北省建设工程招标网_安徽阜阳疫情最新消息_html网站模板免费_semaphore

编程过程中程序员最头疼的两大问题:
1.逻辑混乱 ----- 越界或野指针
2.数据混乱 ------多任务编程是才会遭遇


一、竞态情形

1. 简称竞态,就是程序运行时发生的数据混乱错误
当并发执行的多任务间同一时刻由于使用共享资源不当而导致共享资源的数据与任何一个任务逻辑都不匹配的错误现象
2. 竞态情形错误发生的必要条件:
        多任务
        并发执行
        存在共享资源
        同一时刻使用

即使以上四个条件都满足,竞态情形也不一定发生,这导致竞态情形错误重现成为一个麻烦!!


二、并发控制机制

为了让竞态情形永远不会发生的代码机制。
显然任何并发控制机制的设计都是从避免多任务同一时刻使用共享资源的角度出发进行设计

临界区:每个任务中使用共享资源的代码段被统称为临界区
显然,一个任务的代码在临界区的影响下,可以被划分为四种:

  1. 忙则等待:检查如果有其它任务正在使用共享资源,则本任务需要等待到其它任务使用完毕

    任务在进入区进行等待的方式有两种:

    1> 阻塞等待:即任务进入睡眠态进行等待

    2> 轮询等待:即任务通过循环检查方式来进行等待

  2. 空闲让进:检查如果没有其它任务正在使用共享资源,则本任务应该立即去执行临界区

        可选遵循(有的并发控制遵循,有的不遵循)如下原则:

        有限等待:不能让一个任务永远等待,永远没有机会进入临界区

        该原则是为了避免一种发生几率很小的特例情况----饥饿现象

    一种简单解决饥饿现象的手段:排队

任何一种并发控制机制都必须提供两个核心操作:
P操作:使用共享资源前检查是否有共享资源可用,如无则等待到有后返回,如有则立即返回
V操作:让出共享资源并通知正在等待使用共享资源的任务

核心操作两个基本使用套路:

1. 互斥问题的使用套路
某任务代码:......P操作.....临界区代码.....V操作......

互斥问题:多任务间基于共享资源的使用是竞争关系(争抢使用共享资源)

2. 同步问题的使用套路
并发控制机制要求初始化为:表示共享资源不可用
先做任务----该任务的临界区先运行.............临界区.....V操作.......后做任务----该任务的临界区后运行.......P操作......临界区............

同步问题:多任务间借助于共享资源及其并发控制机制达到协作的目的(在共享资源的影响下,为多个任务的临界区代码规定了固定的执行次序)(任务间是合作关系)

注意事项:使用并发控制机制必须避免出现死锁现象

死锁现象:是由于程序员使用PV操作不当导致某些任务永远在P操作进行等待的错误情况


三、信号量原理 ---- semaphore

struct sem
{原子整型 val;//原子整型:对该整型变量的所有操作都是原子操作(不可被打断的操作)/*>0:当前可用的共享资源个数<0:绝对值表示任务队列中等待使用共享资源的任务数=0:既无共享资源可用,也无任务在等待*/task_queue *ptq;//任务队列
};
//一个信息量就是一个struct sem类型的元素,通过对信息量的操作可以实现对多个共享资源的控制
int sem_p(struct sem *psem)
{/*1. psem->val--;2. if(psem->val < 0){当前任务入队到任务队列进行阻塞等待返回------当本任务从任务队列出队出来}else{返回}*/
}
int sem_v(struct sem *psem)
{/*1. psem->val++;2. if(psen->val <= 0){通知其它第一个正在等待使用共享资源的任务 (将任务队列中的第一个任务出队)返回}else返回*/
}

不同情况下实现的信息量,实现原理是相同的,但p、v操作函数名的命名可能会不同:
常用P操作函数名:semwait、down、sem_p 
常用v操作函数名:semsignal、up、sem_v 

一种特殊的信号量,其成员 val 只有两个取值可能 1 (二元信号量),这样的信号量被称为互斥锁(mutex lock)

struct mutex
{原子整型 val;//原子整型:对该整型变量的所有操作都是原子操作(不可被打断的操作)/*=0:共享资源不可用=1:共享资源可用*/task_queue *ptq;//任务队列
};
//一个互斥锁就是一个struct mutex类型的元素,通过对互斥锁的操作可以实现对单个共享资源的控制
int mutex_lock(struct mutex *plck)
{/*if(psem->val == 1){psem->val = 0;返回}else{当前任务入队到任务队列进行阻塞等待返回------当本任务从任务队列出队出来}*/
}
int mutex_unlock(struct mutex *plck)
{/*if(任务队列为空){psem->val = 1;返回}else{通知其它第一个正在等待使用共享资源的任务 (将任务队列中的第一个任务出队)返回}*/
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com