(学习日记)2024.03.15:UCOSIII第十七节:任务的挂起和恢复

news2025/1/12 2:55:39

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2024.03.15

  • 三十一、UCOSIII:任务的挂起和恢复
    • 1、实现任务的挂起和恢复
      • 1. 定义任务的状态
      • 2. 修改任务控制块TCB
      • 3. 编写任务挂起和恢复函数
        • - OSTaskSuspend()函数
        • - OSTaskResume()函数
    • 2、main()函数
    • 3、实验现象

三十一、UCOSIII:任务的挂起和恢复

本章开始,我们让OS的任务支持挂起和恢复的功能,挂起就相当于暂停,暂停后任务从就绪列表中移除, 恢复即重新将任务插入就绪列表。
一个任务挂起多少次就要被恢复多少次才能重新运行。

1、实现任务的挂起和恢复

1. 定义任务的状态

在任务实现挂起和恢复的时候,要根据任务的状态来操作,任务的状态不同,操作也不同。
有关任务状态的宏定义在os.h中实现, 总共有9种状态

/* ---------- 任务的状态 -------*/
#define  OS_TASK_STATE_BIT_DLY               (OS_STATE)(0x01u)/*   /-------- 挂起位          */

#define  OS_TASK_STATE_BIT_PEND              (OS_STATE)(0x02u)/*   | /-----  等待位          */

#define  OS_TASK_STATE_BIT_SUSPENDED         (OS_STATE)(0x04u)/*   | | /---  延时/超时位      */

#define  OS_TASK_STATE_RDY                    (OS_STATE)(  0u)/*   0 0 0  就绪               */
#define  OS_TASK_STATE_DLY                    (OS_STATE)(  1u)/*   0 0 1  延时或者超时        */
#define  OS_TASK_STATE_PEND                   (OS_STATE)(  2u)/*   0 1 0  等待               */
#define  OS_TASK_STATE_PEND_TIMEOUT           (OS_STATE)(  3u)/*   0 1 1  等待+超时*/
#define  OS_TASK_STATE_SUSPENDED              (OS_STATE)(  4u)/*   1 0 0  挂起               */
#define  OS_TASK_STATE_DLY_SUSPENDED          (OS_STATE)(  5u)/*   1 0 1  挂起 + 延时或者超时*/
#define  OS_TASK_STATE_PEND_SUSPENDED         (OS_STATE)(  6u)/*   1 1 0  挂起 + 等待         */
#define  OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED (OS_STATE)(  7u)/*   1 1 1  挂起 + 等待 + 超时*/
#define  OS_TASK_STATE_DEL                    (OS_STATE)(255u)

2. 修改任务控制块TCB

为了实现任务的挂起和恢复,需要先在任务控制中TCB中添加任务的状态TaskState和任务挂起计数器SusPendCtr这两个成员

struct os_tcb {
    CPU_STK         *StkPtr;
    CPU_STK_SIZE    StkSize;

    /* 任务延时周期个数 */
    OS_TICK         TaskDelayTicks;

    /* 任务优先级 */
    OS_PRIO         Prio;

    /* 就绪列表双向链表的下一个指针 */
    OS_TCB          *NextPtr;
    /* 就绪列表双向链表的前一个指针 */
    OS_TCB          *PrevPtr;

    /*时基列表相关字段*/
    OS_TCB          *TickNextPtr;
    OS_TCB          *TickPrevPtr;
    OS_TICK_SPOKE   *TickSpokePtr;

    OS_TICK         TickCtrMatch;
    OS_TICK         TickRemain;

    /* 时间片相关字段 */
    OS_TICK              TimeQuanta;
    OS_TICK              TimeQuantaCtr;

    OS_STATE             TaskState;		//(1)

#if OS_CFG_TASK_SUSPEND_EN > 0u		//(2)
    /* 任务挂起函数OSTaskSuspend()计数器 */
    OS_NESTING_CTR       SuspendCtr;		//(3)
#endif

};
  • (1):TaskState用来表示任务的状态,在本章之前,任务出现了两种状态,一是任务刚刚创建好的时候, 处于就绪态,调用阻塞延时函数的时候处于延时态。本章要实现的是任务的挂起态,再往后的章节中还会有等待态,超时态, 删除态等。
  • (2):任务挂起功能是可选的,通过宏OS_CFG_TASK_SUSPEND_EN来控制,该宏在os_cfg.h文件中定义。
  • (3):任务挂起计数器,任务每被挂起一次,SuspendCtr递增一次,一个任务挂起多少次就要被恢复多少次才能重新运行。

3. 编写任务挂起和恢复函数

- OSTaskSuspend()函数
#if OS_CFG_TASK_SUSPEND_EN > 0u
void   OSTaskSuspend (OS_TCB  *p_tcb,
                    OS_ERR  *p_err)
{
    CPU_SR_ALLOC();


    #if 0/* 屏蔽开始 */    			//(1)
    #ifdef OS_SAFETY_CRITICAL
    /* 安全检查,OS_SAFETY_CRITICAL_EXCEPTION()函数需要用户自行编写 */
    if (p_err == (OS_ERR *)0)
    {
        OS_SAFETY_CRITICAL_EXCEPTION();
        return;
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
    /* 不能在ISR程序中调用该函数 */
    if (OSIntNestingCtr > (OS_NESTING_CTR)0)
    {
        *p_err = OS_ERR_TASK_SUSPEND_ISR;
        return;
    }
#endif

    /* 不能挂起空闲任务 */
    if (p_tcb == &OSIdleTaskTCB)
    {
        *p_err = OS_ERR_TASK_SUSPEND_IDLE;
        return;
    }

#if OS_CFG_ISR_POST_DEFERRED_EN > 0u
    /* 不能挂起中断处理任务 */
    if (p_tcb == &OSIntQTaskTCB)
    {
        *p_err = OS_ERR_TASK_SUSPEND_INT_HANDLER;
        return;
    }
#endif

#endif/* 屏蔽结束 */  		//(2)

    CPU_CRITICAL_ENTER();

    /* 是否挂起自己 */    		//(3)
    if (p_tcb == (OS_TCB *)0) {
        p_tcb = OSTCBCurPtr;
    }

    if (p_tcb == OSTCBCurPtr) {
    /* 如果调度器锁住则不能挂起自己 */
    if (OSSchedLockNestingCtr > (OS_NESTING_CTR)0) {
            CPU_CRITICAL_EXIT();
            *p_err = OS_ERR_SCHED_LOCKED;
    return;
        }
    }

    *p_err = OS_ERR_NONE;

    /* 根据任务的状态来决定挂起的动作 */		//(4)
    switch (p_tcb->TaskState)
    {
        case OS_TASK_STATE_RDY:		//(5)
            OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
            p_tcb->TaskState  =  OS_TASK_STATE_SUSPENDED;
            p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
            OS_RdyListRemove(p_tcb);
            OS_CRITICAL_EXIT_NO_SCHED();
            break;

        case OS_TASK_STATE_DLY:		//(6)
            p_tcb->TaskState  = OS_TASK_STATE_DLY_SUSPENDED;
            p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
            CPU_CRITICAL_EXIT();
            break;

        case OS_TASK_STATE_PEND:		//(7)
            p_tcb->TaskState  = OS_TASK_STATE_PEND_SUSPENDED;
            p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
            CPU_CRITICAL_EXIT();
            break;

        case OS_TASK_STATE_PEND_TIMEOUT:		//(8)
            p_tcb->TaskState  = OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED;
            p_tcb->SuspendCtr = (OS_NESTING_CTR)1;
            CPU_CRITICAL_EXIT();
            break;

        case OS_TASK_STATE_SUSPENDED:		//(9)
        case OS_TASK_STATE_DLY_SUSPENDED:
        case OS_TASK_STATE_PEND_SUSPENDED:
        case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:
            p_tcb->SuspendCtr++;
            CPU_CRITICAL_EXIT();
            break;

        default:		//(10)
            CPU_CRITICAL_EXIT();
            *p_err = OS_ERR_STATE_INVALID;
            return;
    }

    /* 任务切换 */
    OSSched();		//(11)
}
#endif
  • (1)和(2):这部分代码是为了程序的健壮性写的代码,即是加了各种判断, 避免用户的误操作。在μC/OS-III中,这段代码随处可见,但为了讲解方便,我们把这部分代码注释掉, 里面涉及的一些宏和函数我们均不实现,只需要了解即可,在后面的讲解中,要是出现这段代码, 我们直接删除掉,删除掉也不会影响核心功能。
  • (3):如果任务挂起的是自己,则判断下调度器是否锁住,如果锁住则退出返回错误码,没有锁则继续往下执行。
  • (4):根据任务的状态来决定挂起操作。
  • (5):任务在就绪状态,则将任务的状态改为挂起态,挂起计数器置1,然后从就绪列表删除。
  • (6):任务在延时状态,则将任务的状态改为延时加挂起态,挂起计数器置1,不用改变TCB的位置,即还是在延时的时基列表。
  • (7):任务在等待状态,则将任务的状态改为等待加挂起态,挂起计数器置1,不用改变TCB的位置,即还是在等待列表等待。 等待列表暂时还没有实现,将会在后面的章节实现。
  • (8):任务在等待加超时态, 则将任务的状态改为等待加超时加挂起态,挂起计数器置1,不用改变TCB的位置,即还在等待和时基这两个列表中。
  • (9):只要有一个是挂起状态,则将挂起计数器加一操作,不用改变TCB的位置。
  • (10):其他状态则无效,退出返回状态无效错误码。
  • (11):任务切换。凡是涉及改变任务状态的地方,都需要进行任务切换。
- OSTaskResume()函数

OSTaskResume()函数用于恢复被挂起的函数,但是不能恢复自己,挂起倒是可以挂起自己

#if OS_CFG_TASK_SUSPEND_EN > 0u
void  OSTaskResume (OS_TCB  *p_tcb,
                    OS_ERR  *p_err)
{
    CPU_SR_ALLOC();

#if 0/* 屏蔽开始 */			//(1)
	#ifdef OS_SAFETY_CRITICAL
	/* 安全检查,OS_SAFETY_CRITICAL_EXCEPTION()函数需要用户自行编写 */
	if (p_err == (OS_ERR *)0) {
        OS_SAFETY_CRITICAL_EXCEPTION();
	return;
    }
#endif

#if OS_CFG_CALLED_FROM_ISR_CHK_EN > 0u
	/* 不能在ISR程序中调用该函数 */
	if (OSIntNestingCtr > (OS_NESTING_CTR)0) {
        *p_err = OS_ERR_TASK_RESUME_ISR;
	return;
    }
#endif


    CPU_CRITICAL_ENTER();
#if OS_CFG_ARG_CHK_EN > 0u
	/* 不能自己恢复自己 */
	if ((p_tcb == (OS_TCB *)0) ||
        (p_tcb == OSTCBCurPtr)) {
        CPU_CRITICAL_EXIT();
        *p_err = OS_ERR_TASK_RESUME_SELF;
	return;
    }
#endif

#endif/* 屏蔽结束 */			//(2)

    *p_err  = OS_ERR_NONE;
	/* 根据任务的状态来决定挂起的动作 */
	switch (p_tcb->TaskState) {			//(3)
	case OS_TASK_STATE_RDY:			//(4)
	case OS_TASK_STATE_DLY:
	case OS_TASK_STATE_PEND:
	case OS_TASK_STATE_PEND_TIMEOUT:
	    CPU_CRITICAL_EXIT();
	    *p_err = OS_ERR_TASK_NOT_SUSPENDED;
		break;

	case OS_TASK_STATE_SUSPENDED:			//(5)
	    OS_CRITICAL_ENTER_CPU_CRITICAL_EXIT();
	    p_tcb->SuspendCtr--;
		if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
            p_tcb->TaskState = OS_TASK_STATE_RDY;
            OS_TaskRdy(p_tcb);
        }
        OS_CRITICAL_EXIT_NO_SCHED();
		break;

	case OS_TASK_STATE_DLY_SUSPENDED:			//(6)
	        p_tcb->SuspendCtr--;
		if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
            p_tcb->TaskState = OS_TASK_STATE_DLY;
        }
        CPU_CRITICAL_EXIT();
		break;

	case OS_TASK_STATE_PEND_SUSPENDED:			//(7)
        p_tcb->SuspendCtr--;
	if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
            p_tcb->TaskState = OS_TASK_STATE_PEND;
        }
        CPU_CRITICAL_EXIT();
		break;

	case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED:			//(8)
        p_tcb->SuspendCtr--;
		if (p_tcb->SuspendCtr == (OS_NESTING_CTR)0) {
            p_tcb->TaskState = OS_TASK_STATE_PEND_TIMEOUT;
        }
        CPU_CRITICAL_EXIT();
		break;

	default:			//(9)
        CPU_CRITICAL_EXIT();
        *p_err = OS_ERR_STATE_INVALID;
	return;
    }

/* 任务切换 */
    OSSched();			//(10)
}
#endif
  • (1)和(2):这部分代码是为了程序的健壮性写的代码,即是加了各种判断,避免用户的误操作。 在μC/OS-III中,这段代码随处可见,但为了讲解方便,我们把这部分代码注释掉,里面涉及的一些宏和函数我们均不实现, 只需要了解即可,在后面的讲解中,要是出现这段代码,我们直接删除掉,删除掉也不会影响核心功能。
  • (3):根据任务的状态来决定恢复操作。
  • (4):只要任务没有被挂起,则退出返回任务没有被挂起的错误码。
  • (5):任务只在挂起态, 则递减挂起计数器SuspendCtr,如果SuspendCtr等于0,则将任务的状态改为就绪态,并让任务就绪。
  • (6):任务在延时加挂起态, 则递减挂起计数器SuspendCtr,如果SuspendCtr等于0,则将任务的状态改为延时态。
  • (7):任务在等待加挂起态, 则递减挂起计数器SuspendCtr,如果SuspendCtr等于0,则将任务的状态改为等待态。
  • (8):任务在等待加超时加挂起态, 则递减挂起计数器SuspendCtr,如果SuspendCtr等于0,则将任务的状态改为等待加超时态
  • (9):其他状态则无效,退出返回状态无效错误码。
  • (10):任务切换。凡是涉及改变任务状态的地方,都需要进行任务切换。

2、main()函数

这里,我们创建任务1、2和3,其中任务的优先级为1,任务2的优先级为2,任务3的优先级为3。
任务1将自身的flag每翻转一次后均将自己挂起, 任务2在经过两个时钟周期后将任务1恢复,任务3每隔一个时钟周期翻转一次。

int main(void)
{
    OS_ERR err;


    /* CPU初始化:1、初始化时间戳 */
    CPU_Init();

    /* 关闭中断 */
    CPU_IntDis();

    /* 配置SysTick 10ms 中断一次 */
    OS_CPU_SysTickInit (10);

    /* 初始化相关的全局变量 */
    OSInit(&err);

    /* 创建任务 */
    OSTaskCreate( (OS_TCB       *)&Task1TCB,
                (OS_TASK_PTR   )Task1,
                (void         *)0,
                (OS_PRIO       )1,
                (CPU_STK      *)&Task1Stk[0],
                (CPU_STK_SIZE  )TASK1_STK_SIZE,
                (OS_TICK       )0,
                (OS_ERR       *)&err );

    OSTaskCreate( (OS_TCB       *)&Task2TCB,
                (OS_TASK_PTR   )Task2,
                (void         *)0,
                (OS_PRIO       )2,
                (CPU_STK      *)&Task2Stk[0],
                (CPU_STK_SIZE  )TASK2_STK_SIZE,
                (OS_TICK       )0,
                (OS_ERR       *)&err );

    OSTaskCreate( (OS_TCB       *)&Task3TCB,
                (OS_TASK_PTR   )Task3,
                (void         *)0,
                (OS_PRIO       )3,
                (CPU_STK      *)&Task3Stk[0],
                (CPU_STK_SIZE  )TASK3_STK_SIZE,
                (OS_TICK       )0,
                (OS_ERR       *)&err );

    /* 启动OS,将不再返回 */
    OSStart(&err);
}

void Task1( void *p_arg )
{
    OS_ERR err;

    for ( ;; ) {
        flag1 = 1;
        OSTaskSuspend(&Task1TCB,&err);
        flag1 = 0;
        OSTaskSuspend(&Task1TCB,&err);
    }
}

void Task2( void *p_arg )
{
    OS_ERR err;

    for ( ;; ) {
        flag2 = 1;
        OSTimeDly(1);
        //OSTaskResume(&Task1TCB,&err);
        flag2 = 0;
        OSTimeDly(1);;
        OSTaskResume(&Task1TCB,&err);
    }
}

void Task3( void *p_arg )
{
    for ( ;; ) {
        flag3 = 1;
        OSTimeDly(1);
        flag3 = 0;
        OSTimeDly(1);
    }
}

3、实验现象

进入软件调试,单击全速运行按钮就可看到实验波形,具体见图
在这里插入图片描述
可以看到任务2和任务3的波形图是一样的, 任务1的波形周期是任务2的两倍,与代码实现相符。如果想实现其他效果可自行修改代码实现。

其中,任务二与任务三是靠任务阻塞来完成延时的,只与系统时钟相关。
而任务一每次翻转都会将自己挂起,必须靠任务二将自己恢复才能继续运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT提示词方法的原理

关于提示词,我之前的一些文章可以参考: 【AIGC】AI作图最全提示词prompt集合(收藏级)https://giszz.blog.csdn.net/article/details/134815245?ydrefereraHR0cHM6Ly9tcC5jc2RuLm5ldC9tcF9ibG9nL21hbmFnZS9hcnRpY2xlP3NwbT0xMDExL…

SAR ADC教程系列5——FFT频谱泄露以及相干采样

频谱泄露的出现以及如何规避? 为什么要相干采样? 1.分析ADC输出信号的频谱工具:DFT(Discrete Fourier Transform) 重点:DFT相邻频谱频率间隔为fs/N 如何规避频谱泄露? 对于DFT,它对于接收到的信…

2024 年(第 12 届)“泰迪杯”数据挖掘挑战赛——A 题:生产线的故障自动识别与人员配置具体思路以及源代码分析

一、问题背景 随着新兴信息技术的大规模应用,工业生产线的智能化控制技术日益成熟。自动生产线 可以自动完成物品传送、物料填装、产品包装和质量检测等过程,极大地提高了生产效率和 产品质量,减少了生产成本。自动生产线融入故障智能报警…

学习笔记--强化学习(1)

参考:https://blog.csdn.net/koulongxin123/article/details/122676149 1.什么是强化学习? (1)定义 基于环境的反馈而行动,通过不断与环境的交互、试错,最终完成特定目的或者使得整体行动收益最大化(是一种通过与环境…

echarts实践总结(常用一):柱状图(特点:渐变色、点击缩放、左右滑动、悬浮展示样式)

目录 第一章 echarts基本使用 第二章 echarts实践——柱状图 效果展示 第一章 echarts基本使用 Echarts常用配置项(详细入门)_echarts配置项手册-CSDN博客 第二章 echarts实践——柱状图 最近接到这么一个需求,需要画页面,然后有这么几个echarts的图需…

asp.net 作业星软件系统

asp.net 作业星软件系统 用户功能:分教师和家长(学生) 注册登录:登录部分是用户名密码,以及教师和家长(学生)的勾选; 注册包括用户名密码确认密码再次确认密码(与上方输入的密码比对)身份班级设置找回账号的问题和答案…

【计算机网络】什么是http?

​ 目录 前言 1. 什么是HTTP协议? 2. 为什么使用HTTP协议? 3. HTTP协议通信过程 4. 什么是url? 5. HTTP报文 5.1 请求报文 5.2 响应报文 6. HTTP请求方式 7. HTTP头部字段 8. HTTP状态码 9. 连接管理 长连接与短连接 管线化连接…

养鸡厂用这个开源监控方案,应该很棒

软件介绍 WVP-PRO是基于GB/T 28181-2016标准的流媒体平台,依托于优秀的开源流媒体服务 ZLMediaKit 提供全面且丰富的功能。该软件允许用户将 IPC 摄像头接入平台,支持28181、rtsp、rtmp、flv等协议,可实现视频流发送到其他平台,广…

记日志打印引起接口慢问题排查

其他系统调用本接口,其他系统反馈接口慢,查看接口用时0.07s,但仔细观察日志发现接口确实慢了用时5.978s; 日志写入NAS盘,非本地写入肯定会有一定的延时,看日志打印策略是同步滚动打印,改成异步打…

软件实例,餐厅酒水寄存管理系统软件,酒水寄存登记表软件操作教程

软件实例,餐厅酒水寄存管理系统软件,酒水寄存登记表软件操作教程 一、前言 以下软件操作以 佳易王酒水寄存管理系统软件V16.0为例说明 件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 1、酒水寄存管理系统软件可以管理多个品类的物…

[NOIP1998 提高组] 拼数

[NOIP1998 提高组] 拼数 题目描述 设有 n n n 个正整数 a 1 … a n a_1 \dots a_n a1​…an​,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。 输入格式 第一行有一个整数,表示数字个数 n n n。 第二行有 n n …

小白DB补全计划Day1-LeetCode:SQL基本操作select

前言:找工作(主人)的任务罢了 链接:1757. 可回收且低脂的产品 - 力扣(LeetCode) 584. 寻找用户推荐人 - 力扣(LeetCode) 来源:LeetCode 对DB篇的SQL章不太知道怎么写…

8.Python从入门到精通—Python 字符串,转义字符,字符串运算符

8.Python从入门到精通—Python 字符串,转义字符,字符串运算符 Python 字符串创建字符串访问字符串中的字符字符串切片字符串操作符字符串方法 Python 转义字符Python字符串运算符 Python 字符串 在 Python 中,字符串是一种基本数据类型,用于表示文本数据…

深度学习pytorch——Tensor维度变换(持续更新)

view()打平函数 需要注意的是打平之后的tensor是需要有物理意义的,根据需要进行打平,并且打平后总体的大小是不发生改变的。 并且一定要谨记打平会导致维度的丢失,造成数据污染,如果想要恢复到原来的数据形式,是需要…

【全面了解自然语言处理三大特征提取器】RNN(LSTM)、transformer(注意力机制)、CNN

目录 一 、RNN1.RNN单个cell的结构2.RNN工作原理3.RNN优缺点 二、LSTM1.LSTM单个cell的结构2. LSTM工作原理 三、transformer1 Encoder(1)position encoding(2)multi-head-attention(3)add&norm 残差链…

A Workload‑Adaptive Streaming Partitioner for Distributed Graph Stores(2021)

用于分布式图存储的工作负载自适应流分区器 对象:动态流式大图 划分方式:混合割 方法:增量重划分 考虑了图查询算法,基于动态工作负载 考虑了双动态:工作负载动态;图拓扑结构动态 缺点:分配新顶…

C语言基础之输入输出

前言 本次博客会是最有料的博客了,这其中的问题尤其是scanf函数对新手很不友好 我们本次 1会讲解其他的一些输入输出函数,分析他们的优劣点 2本次的参考资料来自于 c primer plus 1scanf函数详解 首先大家了解过scanf的功能吗 1大家已经学到这里了,肯定知道,scanf是从输…

Java Swing游戏开发学习11

内容来自RyiSnow视频讲解 这一节讲的是游戏状态GameState 游戏状态这里是,游戏所处的各种状态,比如游戏中、已暂停、与NPC对话中、与怪物Monster战斗中等等。在不同的状态中,游戏的交互也是不同的,比如按Enter键在游戏中状态&…

第三篇 - 概述- IAB受众和技术标准 - IAB视频广告标准《数字视频和有线电视广告格式指南》

第三篇 - 概述- IAB受众和技术标准​​​​​​​ - 我为什么要翻译介绍美国人工智能科技公司IAB技术标准系列(2) 本文目录 一、IAB技术实验室简介 二、概述及IAB受众 三、资源- IAB倡导的相关视频广告技术标准 四、案例分享-介绍一家数字化营销服务…

每日OJ题_简单多问题dp⑧_力扣188. 买卖股票的最佳时机 IV

目录 力扣188. 买卖股票的最佳时机 IV 状态机分析 解析代码 力扣188. 买卖股票的最佳时机 IV 188. 买卖股票的最佳时机 IV 难度 困难 给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取…