首页 > 编程语言 >3 - 任务调度算法 & 同步与互斥 &队列

3 - 任务调度算法 & 同步与互斥 &队列

时间:2023-09-15 19:57:08浏览次数:38  
标签:执行 队列 互斥 任务 任务调度 数据 指针

之前的都是按照优先级不同允许抢占(不讲道理),不管你在做什么,轮到优先级最高的任务,直接抢占执行

怎样才能讲道理呢?稍微等等嘛,等我做完活你再做

  1 支持抢占,0不支持抢占

 同优先级任务是否交替执行,1交替0不交

 空闲任务是否礼让其他任务

礼让的话,自己的函数逻辑在时间片内只执行一遍,然后调度 

 

不支持抢占就行,最好是做完事情后,自觉放弃占用CPU,例:

 

 

同步

方案1:  任务A执行完毕后置标志位,任务B时刻检查这个标志位变化,这样实现互斥的话浪费CPU资源,因为两个任务优先级一样,时间片轮转,每次都要进入任务B判断下逻辑;

方案2:使用队列,新创建一个队列,任务A和B各自充当生产者和消费者,生产者运行完毕后生产一个数据放入队列,消费者监控队列,从队列获取到值的时候才执行自己的逻辑.     问:监控队列需要消耗CPU资源么

 

互斥:两个任务都要使用窗口打印,不等对方打印完,到了自己的时间片就直接抢占打印;

解决办法1:通过判断标志位,后面的延迟是为了让另外一个任务有机会能抢到时间片,不然的话标志位置0后又立马置1,另外的任务永远无法抢到

隐患:当任务多而且执行次数多的时候,就有几率>1个任务同时通过标志位(一个刚好过了if判断,就被切换出去【还没来得及置1】),然后两个任务轮转执行,打破互斥

 解决办法2:使用队列, 队列中放一个锁(随便某个数值就行),互斥任务执行的时候需要获取这个锁,就是读取到数值,当队列中没有数值的话就进入阻塞状态,直到抢到这个锁,抢到锁之后可以执行自己的逻辑,执行完毕后再把锁放回到队列中  (距离:互斥使用串口,各自打印各自的数据,完整输出完自己的数据)

可能遇到的问题,只有后面创建的任务使用串口,原因:后面的任务释放了锁(写数据到队列),使阻塞的任务进入就绪态,但是后面的任务仍处于执行态,所以又会获得锁,循环

解决办法: 1.进入等待放弃时间片  2.主动切换任务?   问题: 怎么能保证多个互斥任务都能够有机会执行呢

小技巧: 可以把指针(4字节?)放入到队列中,然后传递指针,这样就可以利用队列传输大量数据(指针指向的地址)

 

队列的本质是环形buf缓冲区

创建队列,指定队列长度和每个item的大小,开始的时候头尾指针都指向第一个

写一个任务(默认写到尾部),到指针位置,然后PcwriteTo指向下一个item,等待下次写入。 若是写满的话就可以指定其等待时间(阻塞),然后将这个等待任务放到List_t xTasksWaitingToSend队列中;  有位置可以写的话再将其唤醒,【等待时间为0的话,就直接返回报错】

写指针指到最后一位,然后会回到开头(环)

 

可以使用指定函数写到头部

实际上是写到PcReadFrom指向的位置,然后将其指针-1,下次读的话就先读它,就相当于写数据到头部

 若很多任务都在等待,那么有机会的话先唤醒谁呢? 按照优先级和等待时间来判断

 

常规读

需要指定:读哪个队列?读出的数据放在哪?读不到东西是否等待(等待的话就进等待的队列)

队列初始化的时候PcReadFrom指向最后一个,当开始读的时候,PcReadFrom指针+1(就指向头部)

 

 

邮箱:

长度为1的队列,新数据覆盖旧数据,读数据不会移除(橱窗),第一次调用会因为无数据而阻,一旦写入数据,以后读邮箱总能成功

 

队列集(列集也是队列,之前的队列里面放的是数据,队列集里面放的是队列)

 

准备条件:创建好各自的队列, 然后将各个队列与队列集产生联系,

当按下鼠标的时候,数据会到鼠标的队列中,同时,还会把鼠标的handle放入到队列集中

 PS:往队列A中写N个数据,会导致写队列集N次

 

读队列集,先读出队列,然后从队列中读出数据 (读一次队列,读一次数据)

实际上就是队列的嵌套

 

 

 

8-3 OVER

标签:执行,队列,互斥,任务,任务调度,数据,指针
From: https://www.cnblogs.com/liujinmeng/p/17697903.html

相关文章

  • POJ 2823 Sliding Window 单调队列
    这道题就是用单调队列来维护,但是用G++交TLE,用c++5000多ms,真是囧...代码很丑,就凑合着看吧#include<stdio.h>inta[1000009],que[1000009];intmain(){ intn,k,i,head,tail,flag=1,f; scanf("%d%d",&n,&k); for(i=1;i<=n;i++) scanf("%d",&a[i]); head=......
  • 多任务互斥与同步
    多任务互斥与同步1.互斥和同步概述同步和互斥是用于解决如下两个问题:1)在多任务操作系统中,同时运行的多个任务可能都需要访问/使用同一种资源。2)多个任务之间有依赖关系,某个任务的运行依赖于另一个任务互斥:一个公共资源同一时刻只能被一个进程或线程使用,多个进程或线程不......
  • Linux内核开发:任务调度与内存管理Linux内核开发:任务调度与内存管理
    Linux内核开发:任务调度与内存管理Linux内核是操作系统的核心,负责管理系统资源、硬件设备和应用程序。在Linux内核中,任务调度和内存管理是两个关键的子系统。本文将介绍这两个子系统的基本原理和实现方法。一、任务调度任务调度是操作系统的核心功能之一,它决定了系统中各个进程的执......
  • 队列(Queue)
    一、队列的概念队列是一个先进先出的数据结构。联想一下链表,在单链表中,只能对表尾进行插入,对表头进行结点的删除,这样强限制性的链表,就是所说的队列。也就是说,队列是限定在表的一端进行插入,表的另一端进行删除的数据结构。如图去买票排队,每一列队伍都有一个队尾和队首,先来的先买......
  • 学习笔记之Redis消息队列-基于Stream的消息队列
    学习笔记之Redis消息队列-基于Stream的消息队列Stream是Redis5.0引入的一种新数据类型,可以实现一个功能非常完善的消息队列。其实只需要知道写入消息队列的命令和读取消息队列的命令就行了写入消息队列:XADD读取消息队列的方式之一:XREAD在业务开发中,我们可以循环的调用......
  • 深入研究消息队列05 各消息队列集群架构对比
    23RabbitMQ的集群架构集群构建数据可靠性身份认证资源鉴权可观测性......
  • Java有关队列的基本操作
    什么是队列?队列是一种线性数据结构,队列中的元素只能先进先出;队列的出口端叫做队头,入口端叫做队尾。队列的基本操作1.入队:只允许在队尾的位置放入元素,新元素的下一个位置将会成为新的队尾;publicvoidenQueue(intelement)throwsException{if((rea......
  • Java多线程____BlockingQueue阻塞队列使用
    packagecom.frame.base.thread;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.ArrayBlockingQueue;/***并发编程____阻塞队列*/publicclassBlockingQueueTest{ publicstaticvoidmain(String[]args)throwsInterruptedException{......
  • 25进程/join方法/互斥锁
    代码创建进程"""创建进程的方式有哪些1.鼠标双击桌面一个应用图标2.代码创建创建进程的本质:在内存中申请一块内存空间用于运行相应的程序代码"""#第一种创建进程的方式》》对象#frommultiprocessingimportProcess#importtime###deftask(name)......
  • 队列——链式存储
    核心思路:1、首先定义队列结点,包含数据域和指针域;然后定义链式队列,包含队列节点类型的队头和队尾指针。2、初始化:带头结点:给头结点分配内存,然后队头和队尾指针指向头结点,同时队头指针的next指向NULL。不带头结点:队头和队尾指针都指向NULL。3、入队:带......