【04】FreeRTOS的任务挂起与恢复

news2024/11/23 2:58:28

目录

1.任务的挂起与恢复的API函数

1.1任务挂起函数介绍

1.2任务恢复函数介绍(任务中恢复)

1.3任务恢复函数介绍(中断中恢复)

2.任务挂起与恢复实验

3.任务挂起和恢复API函数“内部实现”解析

3.1vTaskSuspend()

3.2(任务中调用)任务恢复函数vTaskResume()

3.3(中断中调用)任务恢复函数xTaskResumeFromISR()

4.总结


1.任务的挂起与恢复的API函数

API函数描述
vTaskSuspend()挂起任务
vTaskResume()恢复被挂起的任务
xTaskResumeFromISR()在中断中恢复被挂起的任务

挂起:挂起任务类似于暂停,可恢复;删除任务,无法恢复。

恢复:恢复被挂起的任务。

FromISR”:带FromISR后缀是在中断函数中专用的API函数。

1.1任务挂起函数介绍

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

参数介绍: 

xTaskToSuspend:待挂起任务的任务句柄(想挂起哪个任务,就传入哪个任务的任务句柄

 此函数用于挂起任务,使用时需要将FreeRTOSCofig.h中的宏INCLUDE_vTaskSuspend配置为1。

无论优先级多高,被挂起的任务都将不再执行,直到任务被恢复。

注意:当传入的参数为NULL,则代表挂起任务自身(当前正在运行的任务),和删除任务类似。

1.2任务恢复函数介绍(任务中恢复)

任务中恢复挂起函数如下所示(在任务函数中被调用):

void vTaskResume(TaskHandle_t xTaskToResume)

 参数介绍:

xTaskToResume:待恢复任务的任务句柄。

使用此函数需要将FreeRTOSConfig.h中的宏INCLUDE_vTaskSuspend配置为1,和挂起任务需要配置的宏是同一个

注意:任务无论被vTaskSuspend()挂起多少次,只需在任务中调用vTaskResume()恢复一次,就可以继续运行,且被恢复的任务会进入就绪态。

1.3任务恢复函数介绍(中断中恢复)

中断中恢复挂起函数如下所示(在中断函数中被调用):

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume)  

参数介绍:

xTaskToResume:待恢复任务的任务句柄。

函数xTaskResumeFromISR会有两个返回值:

返回值描述
pdTrue任务恢复后需要进行任务切换(恢复的任务优先级,大于当前正在执行的任务优先级
pdFALSE任务恢复后不需要进行任务切换

使用该函数需要将FreeRTOSConfig.h中的宏INCLUDE_vTaskSuspendINCLUDE_xTaskResumeFromISR配置为1。

该函数专用于中断服务函数中,用于解挂(恢复)被挂起的任务。

注意:中断服务函数中要调用FreeRTOS中的API函数,则中断优先级不能高于FreeRTOS所管理的最高优先级。(FreeRTOS所管理的中断优先级是5~15,中断优先级必须在此范围内,如果中断优先级在0~4(FreeRTOS任务优先级是越大越高,而中断优先级是越小越高。),0~4数值比5~15小,优先级高,不属于FreeRTOS所管理的范围)。

2.任务挂起与恢复实验

1、实验目的:学会 使用FreeRTOS中的任务挂起与恢复相关API函数:vTaskSuspend( )vTaskResume( )xTaskResumeFromISR( )

2、实验设计:将设计四个任务:start_task、task1、task2、task3

四个任务的功能如下:

start_task:用来创建其他的三个任务

task1:实现LED0每500ms闪烁一次

task2:实现LED1每500ms闪烁一次

task3:判断按键按下逻辑,KEY0按下,挂起task1,按下KEY1在任务中恢复task1

按下KEY2,在中断中恢复task1(外部中断线实现,并不在task3中

本次实验基于本系列【03】FreeRTOS的任务创建(静态和动态)和删除中的动态创建任务工程实现。

在使用任务挂起相关函数之前,将FreeRTOSCofig.h中的宏配置为1(由于老版本的正点原子中无INCLUDE_xTaskResumeFromISR所以复制新的FreeRTOSConfig.h程序,在文章【3】中有,并且以后文章都将用新的)。

#define INCLUDE_vTaskSuspend			        1
#define INCLUDE_xTaskResumeFromISR              1                       /* 恢复在中断中挂起的任务 */

start_task、task1、task2并不用做修改。修改完的task3如下所示:

/* 任务三,判断按键KEY0,按下KEY0挂起task1,按下KEY1恢复task1*/
void task3( void * pvParameters )
{
    uint8_t key = 0;
    while(1)
    {
        key = KEY_Scan(0);
        if(key == KEY0_PRES)
        {
			printf("task1被挂起\r\n");
			vTaskSuspend(task1_handler);	
        }
		else if (key == KEY1_PRES)
		{
			printf("task1被恢复\r\n");
			vTaskResume(task1_handler);
		}
        vTaskDelay(10);
    }
}

为了方便展示效果,在task1和task2中打印运行次数,freertos_demo.h修改的部分代码如下:

/* 任务一,实现LED0每500ms翻转一次 */
void task1( void * pvParameters )
{
	uint32_t task1_num=0;
    while(1)
    {
        printf("task1_num:%d\r\n",++task1_num);
        LED0=~LED0;
        vTaskDelay(500);
    }
}

/* 任务二,实现LED1每500ms翻转一次 */
void task2( void * pvParameters )
{
	uint32_t task2_num=0;
    while(1)
    {
        printf("task2_num:%d\r\n",++task2_num);
        LED1=~LED1;
        vTaskDelay(500);
    }
}

实验现象

按下KEY0,task1被挂起后不再被执行,按下KEY1,task1被恢复,执行次数从被挂起之前继续累计。

 在HAL库版本程序,“实验4 外部中断实验”中,复制外部中断程序到本项目中(添加.c文件到项目中,并添加.h文件路径),

此处用的程序是2015年版本程序,要删除KEY0中断服务函数,删除KEY0、KEY1、WEAKUP内容,并添加FreeRTOS相关函数,增加extern调用task2任务句柄,根据FreeRTOS官网API函数示例修改中断回调函数,修改完exti.c如下所示

#include "exti.h"
#include "delay.h"
#include "led.h"
#include "key.h"

#include "FreeRTOS.h"
#include "task.h"

extern TaskHandle_t    task2_handler;
//外部中断初始化
void EXTI_Init(void)
{
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOC_CLK_ENABLE();               //开启GPIOC时钟
    
    GPIO_Initure.Pin=GPIO_PIN_13;               //PC13
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING;     //下降沿触发
    GPIO_Initure.Pull=GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    
    //中断线13-PC13
    HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,3);   //抢占优先级为2,子优先级为3
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);         //使能中断线13  
}


//中断服务函数

void EXTI15_10_IRQHandler(void)
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);//调用中断处理公用函数
}

//中断服务程序中需要做的事情
//在HAL库中所有的外部中断服务函数都会调用此函数
//GPIO_Pin:中断引脚号
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    delay_ms(100);      //消抖
    switch(GPIO_Pin)
    {
		BaseType_t xYieldRequired;
        case GPIO_PIN_13:
            if(KEY2==0)  
            {
				xYieldRequired=xTaskResumeFromISR(task2_handler);
				printf("在中断中恢复task2\r\n");
            }
			if(xYieldRequired==pdTRUE)
			{
				portYIELD_FROM_ISR(xYieldRequired);
			}
            break;
    }
}

运行程序,在中断中恢复task2,串口会报:Error: ..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c, 807 类型错误。 报错在port.c的807行,789行提供的网址有详细的报错信息。优先级分组必须全部用作抢占式,不能用作子优先级,所以修改HAL_Init()部分内容如下所示:

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);//中断优先级分组4

修改完此处后,下载程序,发现串口会输出:Error: ..\FreeRTOS\portable\RVDS\ARM_CM4F\port.c, 791 类型错误,从789行的网址中提示,需要将KEY2的中断优先级调整至FreeRTOS管理的优先级范围。修改EXTI_Init()部分内容如下:

    HAL_NVIC_SetPriority(EXTI15_10_IRQn,6,0);   //抢占优先级为6,子优先级为0

再次运行程序,串口将不再报错。

3.任务挂起和恢复API函数“内部实现”解析

此部分解析需根据task.c中对应的API函数查看。

3.1vTaskSuspend()

1、需将宏INCLUDE_vTaskSuspend 配置为 1

#if ( INCLUDE_vTaskSuspend == 1 )

        将宏 INCLUDE_vTaskSuspend配置为1,才能使用vTaskSuspend()函数。

2、根据任务句柄获取任务控制块,如果任务句柄为NULL,表示挂起任务自身

void vTaskSuspend( TaskHandle_t xTaskToSuspend )
    {
        TCB_t * pxTCB;

        taskENTER_CRITICAL();
        {
            /* If null is passed in here then it is the running task that is
             * being suspended. */
            pxTCB = prvGetTCBFromHandle( xTaskToSuspend );

        传入 vTaskSuspend()的参数为要挂起的任务句柄,任务句柄通过调用prvGetTCBFromHandle()函数返回任务控制块。prvGetTCBFromHandle()函数的定义如下,如果是句柄等于NULL则返回当前正在运行的任务控制块,如果不等于NULL,传入什么则返回什么。

#define prvGetTCBFromHandle( pxHandle )    ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) )

 3、将要挂起的任务从相应的状态列表和事件列表中移除

            if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 )
            {
                taskRESET_READY_PRIORITY( pxTCB->uxPriority );
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }

        移除状态列表项, 不管任务处于何种状态,都要移除。如果就绪列表项没有任务了,则将每一位的优先级标志位进行清0。

taskRESET_READY_PRIORITY()函数定义:

    #define taskRESET_READY_PRIORITY( uxPriority )                                                     \
    {                                                                                                  \
        if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \
        {                                                                                              \
            portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) );                        \
        }                                                                                              \
    }
/* Is the task waiting on an event also? */
            if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL )
            {
                ( void ) uxListRemove( &( pxTCB->xEventListItem ) );
            }
            else
            {
                mtCOVERAGE_TEST_MARKER();
            }

        移除事件列表项。挂起任务时 ,不管是否在等待某种事件发生,还是什么,在挂起的同时将需要等待的事件移除,恢复时无需等待事件

 4、将待挂起任务的任务状态列表向插入到挂起态任务列表末尾

            vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) );

        并清除消息通知, 如果要挂起的任务,正在等待消息通知,改为NOT不需要等待。

#if ( configUSE_TASK_NOTIFICATIONS == 1 )
                {
                    BaseType_t x;

                    for( x = 0; x < configTASK_NOTIFICATION_ARRAY_ENTRIES; x++ )
                    {
                        if( pxTCB->ucNotifyState[ x ] == taskWAITING_NOTIFICATION )
                        {
                            /* The task was blocked to wait for a notification, but is
                             * now suspended, so no notification was received. */
                            pxTCB->ucNotifyState[ x ] = taskNOT_WAITING_NOTIFICATION;
                        }
                    }
                }
            #endif /* if ( configUSE_TASK_NOTIFICATIONS == 1 ) */
        }
        taskEXIT_CRITICAL();

5、判断任务调度器是否运行,在运行,更新下一次阻塞时间,防止被挂起任务为下一次阻塞超时任务       

        if( xSchedulerRunning != pdFALSE )
        {
            /* Reset the next expected unblock time in case it referred to the
             * task that is now in the Suspended state. */
            taskENTER_CRITICAL();
            {
                prvResetNextTaskUnblockTime();
            }
            taskEXIT_CRITICAL();
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }

6、如果挂起的是任务自身,且调度器正在运行,需要强制进行一次任务切换;调度器没有运行,判断挂起任务数是否等于任务总数,是:代表所有任务均被挂起,当前控制块赋值为NULL,否:通过函数vTaskSwitchContext()寻找下一个最高优先级任务。

        if( pxTCB == pxCurrentTCB )
        {
            if( xSchedulerRunning != pdFALSE )
            {
                /* The current task has just been suspended. */
                configASSERT( uxSchedulerSuspended == 0 );
                portYIELD_WITHIN_API();
            }
            else
            {
                /* The scheduler is not running, but the task that was pointed
                 * to by pxCurrentTCB has just been suspended and pxCurrentTCB
                 * must be adjusted to point to a different task. */
                if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */
                {
                    /* No other tasks are ready, so set pxCurrentTCB back to
                     * NULL so when the next task is created pxCurrentTCB will
                     * be set to point to it no matter what its relative priority
                     * is. */
                    pxCurrentTCB = NULL;
                }
                else
                {
                    vTaskSwitchContext();
                }
            }
        }
        else
        {
            mtCOVERAGE_TEST_MARKER();
        }
    }

#endif /* INCLUDE_vTaskSuspend */

3.2(任务中调用)任务恢复函数vTaskResume()

1、需将宏INCLUDE_vTaskSuspend 配置为 1

#if ( INCLUDE_vTaskSuspend == 1 )

         函数入口参数只有待恢复的任务句柄,将任务句柄赋值给任务控制块,

    void vTaskResume( TaskHandle_t xTaskToResume )
    {
        TCB_t * const pxTCB = xTaskToResume;

        /* It does not make sense to resume the calling task. */
        configASSERT( xTaskToResume );

        /* The parameter cannot be NULL as it is impossible to resume the
         * currently executing task. */

2、恢复任务不能是正在运行任务 

        任务控制块不能是当前正在执行任务的任务控制块,只能恢复被挂起的任务。

        if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) )
        {
            taskENTER_CRITICAL();
            {

3、判断任务是否在挂起列表中,是:就会将该任务在挂起列表中移除, 将该任务添加到就绪列表中

        移除状态列表项(不管在什么列表,都会被移除)。

                if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE )
                {
                    traceTASK_RESUME( pxTCB );

                    /* The ready list can be accessed even if the scheduler is
                     * suspended because this is inside a critical section. */
                    ( void ) uxListRemove( &( pxTCB->xStateListItem ) );
                    prvAddTaskToReadyList( pxTCB );

 4、判断恢复的任务优先级是否大于当前正在运行的 是的话执行任务切换(任务切换是操作的PendSV中断

                    if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
                    {
                        /* This yield may not cause the task just resumed to run,
                         * but will leave the lists in the correct state for the
                         * next yield. */
                        taskYIELD_IF_USING_PREEMPTION();
                    }

3.3(中断中调用)任务恢复函数xTaskResumeFromISR()

1、  入口参数是待恢复的任务句柄,并存在返回值。 定义三个变量,第一个是返回值,初始化为pdFALSE(0);将待恢复的任务句柄赋值给任务控制块;定义保存当前中断状态的变量。

    BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
    {
        BaseType_t xYieldRequired = pdFALSE;
        TCB_t * const pxTCB = xTaskToResume;
        UBaseType_t uxSavedInterruptStatus;

        configASSERT( xTaskToResume );

2、函数portASSERT_IF_INTERRUPT_PRIORITY_INVALID(),用于检测:调用FreeRTOS的API函数的中断优先级是否在管理范围内以及全部设置为抢占式优先级。

        使用uxSavedInterruptStatus保存当前中断的状态。

        portASSERT_IF_INTERRUPT_PRIORITY_INVALID();
        uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR();

3、关闭freertos可管理中断,防止被其他的中断打断,并返回关闭前basepri寄存器的值 

4、判断任务是否在挂起列表中,有:则检测调度器是否挂起,如果未挂起则判断恢复的任务优先级是否比当前正在运行的优先级大,大则xYieldRequired标记为pdTRUE,表示需要进行一次任务切换;将被恢复的任务从挂起列表删除;插入到就绪列表。如果任务调度器被挂起,将恢复的任务插入到就绪列表prvAddTaskToReadyList中,直到调度器被恢复时再进行任务的处理。

        {
                traceTASK_RESUME_FROM_ISR( pxTCB );

                /* Check the ready lists can be accessed. */
                if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )
                {
                    /* Ready lists can be accessed so move the task from the
                     * suspended list to the ready list directly. */
                    if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority )
                    {
                        xYieldRequired = pdTRUE;

                        /* Mark that a yield is pending in case the user is not
                         * using the return value to initiate a context switch
                         * from the ISR using portYIELD_FROM_ISR. */
                        xYieldPending = pdTRUE;
                    }
                    else
                    {
                        mtCOVERAGE_TEST_MARKER();
                    }

                    ( void ) uxListRemove( &( pxTCB->xStateListItem ) );
                    prvAddTaskToReadyList( pxTCB );

5、将前面保存的basepri的值,恢复回来

        portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus );

6、返回xYieldRequired的值 用于决定是否需要进行任务切换 

        return xYieldRequired;

4.总结

 

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

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

相关文章

Prometheus基础

一、何为Prometheus Prometheus受启发于Google的Brogmon监控系统&#xff08;相似的Kubernetes是从Google的Brog系统演变而来&#xff09;&#xff0c;从2012年开始由前Google工程师在Soundcloud以开源软件的形式进行研发&#xff0c;并且于2015年早期对外发布早期版本。2016年…

【基础】Netty 的基础概念及使用

Netty基本概念理解阻塞与非阻塞同步与异步BIO 与 NIOReactor 模型Netty 基本概念Netty 的执行流程Netty 的模块组件Netty 工作原理Netty 的基本使用Netty ServerNetty Client参考文章基本概念理解 阻塞与非阻塞 阻塞与非阻塞是进程访问数据时的处理方式&#xff0c;根据数据是…

系分 - 案例分析 - 系统维护与设计模式

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录系分 - 案例分析 - 系统维护与设计模式典型例题 1题目描述参考答案典型例题 2题目描述参考答案系分 - 案例分析 - 系统维护与设计模式 典型例题 1 题目描述 某企业两年前自主研发的消防集中控制软件系统…

05-requests添加Cookies与正则表达式

第5讲 requests添加Cookies与正则表达式 整体课程知识点查看 &#xff1a;https://blog.csdn.net/j1451284189/article/details/128713764 本讲总结 request代理使用 request SSL request添加Cookies 数据解析方法简介 数据解析&#xff1a;正则表达式讲解 一、requests 代理 …

【23种设计模式】学习汇总(未完结+思维导图)

获取思维导图翻至底部底部&#xff0c;基本概览博客内容&#xff08;暂未完全完善&#xff0c;期待你的持续关注&#xff09; 写作不易&#xff0c;如果您觉得写的不错&#xff0c;欢迎给博主来一波点赞、收藏~让博主更有动力吧&#xff01; 一.相关内容 在软件工程中&#xf…

关系型数据库RDBMS | 字节青训营笔记

一、经典案例 1、红包雨案例 每年春节&#xff0c;抖音都会有红包雨获得 2、事务 事务(Transaction): 是由一组SQL语句组成的一个程序执行单元(Unit)&#xff0c;它需要满足ACID特性 BEGIN; UPDATE account table SET balance balance - 小目标 WHERE name “抖音; UPDATE…

指数加权平均、动量梯度下降法

目录1.指数加权平均(exponentially weighted averages)这里有一年的温度数据。如果想计算温度的趋势&#xff0c;也就是局部平均值(local average)&#xff0c;或者说移动平均值(moving average)&#xff0c;怎么做&#xff1f;&#xff1a;当天的温度&#xff0c;&#xff1a;…

交换机的基本原理(特别是动态ARP、静态ARP、代理ARP)

第六章&#xff1a;交换机的基本配置 二层交换设备工作在OSI模型的第二层&#xff0c;即数据链路层&#xff0c;它对数据包的转发是建立在MAC&#xff08;Media Access Control &#xff09;地址基础之上的。二层交换设备不同的接口发送和接收数据独立&#xff0c;各接口属于不…

esxi宿主机进入维护模式虚拟机不会自动释放【不会自动迁移出去】解决方法、查看辨别宿主机本地空间和存储池、esxi进入存储内部清理空间

文章目录说明虚拟机不自动释放处理过程报错说明宿主机进入维护模式说明手动迁移报错说明直接启动虚拟机报错说明解决方法报错原因分析解决方法查看辨别宿主机本地空间esxi进入存储内部清理空间进入存储池内存储内部空间清理及原则存储空间说明说明 我当前的esxi主机版本为5.5 …

7亿人养活的眼镜行业,容不下一家县城小店

文|螳螂观察 作者| 青月 如果要盘点那些被暴利眷顾的行业&#xff0c;眼镜零售肯定榜上有名。 从上市企业的财报数据来看&#xff0c;国内眼镜零售行业的首家上市公司——博士眼镜&#xff0c;2021年前三季度的平均毛利率超过60%&#xff1b;国内镜片第一股明月眼镜在2021年…

【C进阶】文件操作

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C语言进阶 ⭐代码仓库&#xff1a;C Advanced 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们…

小程序应用生命周期

小程序应用生命周期生命周期介绍应用生命周期钩子函数参数对象页面生命周期页面生命周期-页面参数组件生命周期生命周期介绍 定义 一个组件或者页面生老病死的过程一堆会在特定时期触发的函数 分类 应用生命周期页面生命周期组件生命周期 应用生命周期钩子函数 属性说明onL…

Xpath Helper 在新版Edge中的安装及解决快捷键冲突问题

&#x1f935;‍♂️ 个人主页老虎也淘气 个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f44d;&#x1f3fb; 收藏…

vue2源码分析-keep-alive组件

简介 keep-alive是Vue.js的一个内置组件。它能够将指定的组件实例保存在内存中&#xff0c;而不是直接将其销毁&#xff0c;它是一个抽象组件&#xff0c;不会被渲染到真实DOM中&#xff0c;也不会出现在父组件链中。 具体用法咱们这里就不再细说了&#xff0c;今天主要是探讨…

JavaEE day2 初识web与HTML

初步了解相关知识 关于端口&#xff08;port&#xff09;&#xff1a;一个端口同一时间只能被一个进程监听&#xff0c;但是一个进程可以监听多个端口 URL的标准格式&#xff1a;协议名称&#xff1a;//主机/资源路径&#xff1f;查询字符串#文档片段 一般协议最常见的为htt…

Java基础之《netty(25)—handler链调用机制》

一、netty的handler的调用机制 1、使用自定义的编码器和解码器来说明netty的handler调用机制。 客户端发送long -> 服务器 服务端发送long -> 客户端 2、案例 二、客户端发送给服务端 1、服务端 NettyServer.java package netty.inboundhandlerAndOutboundhandler;i…

【C++】从0到1入门C++编程学习笔记 - 基础入门篇:程序流程结构

文章目录一、选择结构1.1 if 语句1.2 三目运算符1.3 switch语句二、循环结构2.1 while 循环语句2.2 do...while 循环语句2.3 for 循环语句2.4 嵌套循环三、跳转语句3.1 break 语句3.2 continue 语句3.3 goto 语句C/C支持最基本的三种程序运行结构&#xff1a;顺序结构、选择结构…

MySQL进阶——优化

1、选择最合适的字段属性 Mysql是一种关系型数据库&#xff0c;可以很好地支持大数据量的存储&#xff0c;但是一般来说&#xff0c;数据库中的表越小&#xff0c;在它上面执行的查询也就越快。因此&#xff0c;在创建表的时候&#xff0c;为了获得更好的性能&#xff0c;我们…

腾讯云HiFlow场景连接器 联动对象存储企业网盘,打通数据分发“最后一公里”

对云厂商和企业用户来说&#xff0c;随着数据规模的快速增长&#xff0c;企业除了对存储功能和性能的要求不断增加&#xff0c;也越来越注重数据分发的效率。在传统数据分发的过程中&#xff0c;数据管理员往往需要先在存储桶下载对应的客户方案/交付资料&#xff0c;再使用微信…

LINUX软中断-softirq

前言 关于linux的软中断的文章&#xff0c;在网上可以找到很多&#xff0c;但总觉着讲的都不够深入&#xff0c;打算自己写一下 软中断的感性认识 中断一旦被触发&#xff0c;本地cpu正在运行的不管是什么程序都要让路&#xff0c;让中断程序执行并且执行过程中不能被打断。…