FreeRTOS基础入门——FreeRTOS的任务基础知识(四)

 个人名片:

🎓作者简介:嵌入式领域优质创作者
🌐个人主页:妄北y

📞个人QQ:2061314755

💌个人邮箱:[mailto:2061314755@qq.com]
📱个人微信:Vir2025WBY

🖥️个人公众号:科技妄北
🖋️本文为妄北y原创佳作,独家首发于CSDN🎊🎊🎊
💡座右铭:改造世界固然伟大,但改造自我更为可贵。

专栏导航:

妄北y系列专栏导航:

物联网嵌入式开发项目:大学期间的毕业设计,课程设计,大创项目,各种竞赛项目,全面覆盖了需求分析、方案设计、实施与调试、成果展示以及总结反思等关键环节。📚💼💡

QT基础入门学习:对QT的基础图形化页面设计进行了一个简单的学习与认识,利用QT的基础知识进行了翻金币小游戏的制作。🛠️🔧💭

Linux基础编程:初步认识什么是Linux,为什么学Linux,安装环境,进行基础命令的学习,入门级的shell编程。🍻🎉🖥️

深耕Linux应用开发:分享Linux的基本概念、命令行操作、文件系统、用户和权限管理等,网络编程相关知识,TCP/IP 协议、套接字(Socket)编程等,可以实现网络通信功能。常见开源库的二次开发,如libcurl、OpenSSL、json-c、freetype等💐📝💡

Linux驱动开发:Linux驱动开发是Linux系统不可或缺的组成部分,它专注于编写特殊的程序——驱动程序。这些程序承载着硬件设备的详细信息,并扮演着操作系统与硬件间沟通的桥梁角色。驱动开发的核心使命在于确保硬件设备在Linux系统上顺畅运作,同时实现与操作系统的无缝集成,为用户带来流畅稳定的体验。🚀🔧💻

Linux项目开发:Linux基础知识的实践,做项目是最锻炼能力的一个学习方法,这里我们会学习到一些简单基础的项目开发与应用,而且都是毕业设计级别的哦。🤸🌱🚀

非常期待与您一同在这个广阔的互联网天地里,携手探索知识的海洋,互相学习,共同进步。🌐💫🌱 熠熠星光,照亮我们的成长之路

✨✨ 欢迎订阅本专栏,对专栏内容任何问题都可以随时联系博主,共同书写属于我们的精彩篇章!✨✨

文章介绍:

📚本篇文章将深入剖析FreeRTOS学习的精髓与奥秘,与您一同分享相关知识!🎉🎉🎉

若您觉得文章尚可入目,期待您能慷慨地送上点赞、收藏与分享的三连支持!您的每一份鼓励,都是我创作路上源源不断的动力。让我们携手并进,共同奔跑,期待在顶峰相见的那一天,共庆辉煌!🚀🚀🚀

🙏衷心感谢大家的点赞👍、收藏⭐和评论✍️,您的支持是我前进的动力!

目录:

目录

目录:

一、FreeRTOS任务特性:

1.1  简单:

1.2 没有使用限制:

1.3 支持抢占:

1.4 支持优先级:

1.5 每个任务都拥有堆栈导致了RAM使用量增大:

1.6 如果使用抢占的话的必须仔细的考虑重入的问题:

二、FreeRTOS任务状态:

2.1 运行态(Running):

2.2 就绪态(Ready):

2.3 阻塞态(Blocked):

2.4 挂起态(Suspended):

三、任务优先级

3.1 优先级范围:

3.2 优先级和硬件支持:

3.3 优先级的含义:

3.4 任务调度:

3.5 时间片轮转调度:

3.6 小结:

四、任务实现:

4.1 任务函数的概念

4.2 任务函数的结构

4.3 任务函数详细执行过程

五、任务控制块:

六、任务堆栈

6.1 FreeRTOS任务堆栈管理

6.2 创建任务

1. 动态方法:xTaskCreate():

2. 静态方法:xTaskCreateStatic()

6.3 堆栈大小


一、FreeRTOS任务特性:

使用实时操作系统(RTOS)时,可以将实时应用作为一个独立的任务来运行。每个任务都有自己的运行环境,包括堆栈空间、寄存器状态等,这些环境是独立的,不依赖于系统中的其他任务或RTOS调度器。

RTOS的核心功能之一是任务调度,它负责决定在任何给定的时间点上运行哪个任务。由于在任何时刻只能有一个任务在运行,RTOS调度器需要不断地在任务之间进行切换,即开启一个任务并关闭其他任务。这种切换过程称为任务切换(task switching)或上下文切换(context switching)。

在任务切换过程中,RTOS调度器必须确保当前运行的任务的上下文环境(包括寄存器值、程序计数器、堆栈指针等)被正确地保存,以便在任务再次被调度运行时能够恢复到之前的状态。这是通过将当前任务的上下文信息保存到该任务的堆栈中来实现的。当任务被重新调度时,RTOS调度器会从堆栈中恢复这些上下文信息,从而使任务能够从上次中断的地方继续执行。

任务本身不需要了解RTOS调度器的具体行为,它们只需要按照RTOS提供的API进行编程,例如创建任务、挂起任务、恢复任务等。RTOS调度器负责管理任务的执行顺序和时间,确保系统的实时性和任务的正确执行。

1.1  简单:

FreeRTOS设计简洁,容易理解和使用。它提供了一个基本但功能强大的API,用于创建和管理任务、队列、信号量和其他实时操作系统(RTOS)功能。

1.2 没有使用限制:

FreeRTOS是开源的,不存在使用上的限制。开发人员可以自由地在各种项目中使用和修改FreeRTOS代码,适用于商业和非商业用途。

1.3 支持抢占:

FreeRTOS支持基于优先级的抢占式调度。高优先级任务可以打断低优先级任务的执行,确保关键任务能及时运行。

1.4 支持优先级:

FreeRTOS允许为每个任务分配优先级。任务的调度基于其优先级,高优先级任务获得更多的CPU时间。

1.5 每个任务都拥有堆栈导致了RAM使用量增大:

每个任务在创建时分配一个独立的堆栈空间。这确保了任务之间的内存隔离,但也会增加总的RAM消耗,尤其是在任务数量较多的情况下。

1.6 如果使用抢占的话的必须仔细的考虑重入的问题:

在抢占式调度的环境中,任务可能会在任意时刻被打断,这可能会导致重入问题。开发人员需要确保代码是线程安全的,特别是在访问共享资源时,常用的技术包括使用信号量、互斥锁等机制。

这些特性使FreeRTOS成为一个灵活且广泛应用的实时操作系统,适用于从简单的嵌入式系统到复杂的工业和消费类设备。

二、FreeRTOS任务状态:

2.1 运行态(Running)

 任务处于运行态时,表示它当前正在被处理器执行。

 在单核处理器系统中,任意时刻只有一个任务可以处于运行态。

2.2 就绪态(Ready)

 任务已经准备好执行,但由于处理器正被其他更高优先级或同优先级的任务占用,因此还没有被执行。

 一旦处理器空闲或者当前运行的任务被阻塞或挂起,就绪态的任务有机会进入运行态。

2.3 阻塞态(Blocked)

 任务在等待某些特定事件(如I/O操作完成、信号量、互斥量等)时进入阻塞态。

 阻塞态任务在等待的事件发生或者超时时间到达时会转换为就绪态。

2.4 挂起态(Suspended)

 任务在挂起态时不会被调度器调度,类似于阻塞态,但没有超时时间限制。

 任务通过调用vTaskSuspend()进入挂起态,通过调用xTaskResume()退出挂起态。

  

  • 就绪态 → 运行态:如果调度器选择就绪态的任务运行。
  • 运行态 → 阻塞态:任务等待某个事件或资源。
  • 运行态 → 就绪态:任务在时间片用完后被调度器切换出。
  • 阻塞态 → 就绪态:等待的事件发生或超时。
  • 运行态 → 挂起态:任务调用了vTaskSuspend()
  • 挂起态 → 就绪态:任务调用了xTaskResume()

三、任务优先级

3.1 优先级范围

每个任务在FreeRTOS中可以分配一个优先级,范围是从 0 到 configMAX_PRIORITIES - 1

configMAX_PRIORITIES 是在 FreeRTOSConfig.h 文件中定义的。

3.2 优先级和硬件支持

在一些硬件平台上,如果支持“计算前导零”指令(如Cortex-M处理器),并且宏 configUSE_PORT_OPTIMISED_TASK_SELECTION 设置为 1,那么 configMAX_PRIORITIES 不能超过 32。这是因为这些硬件优化指令只能处理32个优先级以内的任务。

在其他情况下,configMAX_PRIORITIES 可以为任意值。但为了优化RAM的使用,建议设置为应用所需的最小值。

3.3 优先级的含义

优先级数字越低表示任务的优先级越低。优先级为 0 是最低优先级,configMAX_PRIORITIES - 1 是最高优先级。

系统的空闲任务优先级为 0,这是最低优先级。

3.4 任务调度:

FreeRTOS调度器确保高优先级的任务获取处理器使用权。只有处于就绪态的最高优先级任务会运行。

3.5 时间片轮转调度

如果宏 configUSE_TIME_SLICING 定义为 1(默认情况下它在 FreeRTOS.h 文件中定义为 1),多个任务可以共享同一个优先级。

在这种情况下,具有相同优先级的就绪态任务会使用时间片轮转调度器进行调度,从而分享处理器时间。

3.6 小结:

1. 优先级设置:优先级从 0 到 configMAX_PRIORITIES - 10 最低,configMAX_PRIORITIES - 1 最高。

2. 硬件和优化:在支持硬件优化指令的情况下,优先级不能超过32。

3. 调度机制:FreeRTOS使用优先级调度,高优先级任务优先运行。如果 configUSE_TIME_SLICING 为 1,那么相同优先级的任务会进行时间片轮转调度。

四、任务实现:

在FreeRTOS中,任务是操作系统的基本执行单元,每个任务实际上就是一个独立的执行流。为了创建一个任务,你需要定义一个任务函数,这个函数包含了该任务需要完成的所有工作。

4.1 任务函数的概念

1. 工作单元:任务函数是一个独立的工作单元,它定义了该任务需要完成的具体操作。比如在流水灯的例子中,任务函数将包含点亮和熄灭LED灯的逻辑。

2. 循环执行:任务函数通常包含一个无限循环,这样任务一旦启动就会在这个循环中不断地运行,直到被显式删除或者系统重启。这个循环体内会有任务所需的操作,比如读取传感器数据、处理通信、控制设备等。

3. 调度管理:FreeRTOS的调度器会管理这些任务函数的执行,确保每个任务在适当的时间获得CPU资源执行。任务函数本身不需要担心调度的细节,只需要专注于其核心工作。

4.2 任务函数的结构

1. 初始化部分:在循环开始前,任务函数通常会进行一些初始化操作,比如设置初始状态、配置硬件资源等。

2. 无限循环部分:这是任务函数的主体,包含任务的主要逻辑。每个任务函数通常都会有一个无限循环,在这个循环中执行任务的核心操作。

3. 任务延时:为了避免占用过多的CPU资源,任务函数通常会在每次循环中调用延时函数,使任务进入阻塞状态一段时间,等待下一次执行。这通常是通过FreeRTOS提供的延时函数实现的。

// 任务函数
void vATaskFunction(void *pvParameters)
{for(;;) // 无限循环{// 任务应用程序// 在这里添加你的任务代码vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒(1000毫秒)/* 不能从任务函数中返回或者退出,从任务函数中返回或退出的话就会调用configASSERT,前提是你定义了configASSERT。如果一定要从任务函数中退出的话,那一定要调用函数vTaskDelete(NULL)来删除此任务。*/}// 下面的代码通常不会被执行,因为任务函数是一个无限循环。// 如果确实需要退出任务,可以通过调用vTaskDelete(NULL)来删除此任务。vTaskDelete(NULL);
}

4.3 任务函数详细执行过程

1. 任务函数的定义:任务函数是FreeRTOS任务的核心部分,具有以下特点:

  • 返回类型: 一定是void类型,即无返回值。
  • 参数: 只能是void*类型的指针,通常用来传递参数给任务。
  • 任务名: 可以根据实际情况自定义任务函数名。

2. 任务的执行过程:

  • 任务的执行过程通常是一个无限循环。常见的方式是使用for(;;)while(1)来实现。

3. 任务代码:

  • 循环内的代码就是具体任务需要执行的操作。
  • 这部分代码可以包含各种逻辑操作、数据处理、外设控制等。

4. 任务调度和延时:

  • FreeRTOS提供了多种方式来实现任务调度,其中最常用的是延时函数,如vTaskDelay
  • 其他能引发任务切换的API函数也可以使用,比如请求信号量、队列操作等。

5. 任务的删除:

  • 任务函数一般不允许跳出循环。如果必须跳出循环,则需要调用vTaskDelete(NULL)来删除此任务。
  • 删除任务是为了释放资源,防止任务继续执行。

FreeRTOS的任务函数结构是非常严谨而规范的,它为实时操作系统提供了灵活而强大的任务管理功能。 

五、任务控制块:

FreeRTOS的每个任务都有一些属性需要存储,这些属性被集合在一个结构体中,这个结构体被称为任务控制块(Task Control Block, TCB)。在创建任务时,通过调用 xTaskCreate() 函数,FreeRTOS 会自动为每个任务分配一个 TCB。

在较老版本的 FreeRTOS 中,这个任务控制块结构体被命名为 tskTCB,而在新版本中重命名为 TCB_t。虽然名称有所更改,但它们在本质上是相同的。这个结构体在文件 tasks.c 中定义。

换句话说,任务控制块(TCB_t)是 FreeRTOS 中用于管理任务的核心数据结构,它包含了任务执行所需的各种信息。在创建任务时,FreeRTOS 会自动初始化并分配这个结构体,以管理任务的生命周期和状态。

typedef struct tskTaskControlBlock
{volatile StackType_t	*pxTopOfStack;	/*< 指向任务堆栈上最后一个放置的项的位置。这必须是TCB结构体的第一个成员。 */#if ( portUSING_MPU_WRAPPERS == 1 )xMPU_SETTINGS	xMPUSettings;		/*< MPU设置作为端口层的一部分定义。这必须是TCB结构体的第二个成员。 */#endifListItem_t			xStateListItem;	/*< 任务的状态列表项引用的列表表示该任务的状态(就绪、阻塞、挂起)。 */ListItem_t			xEventListItem;		/*< 用于从事件列表引用任务。 */UBaseType_t			uxPriority;			/*< 任务的优先级。0 是最低优先级。 */StackType_t			*pxStack;			/*< 指向堆栈的起始位置。 */char				pcTaskName[ configMAX_TASK_NAME_LEN ];/*< 创建任务时给出的描述性名称。仅便于调试。 */ /*lint !e971 未限定的char类型仅允许用于字符串和单个字符。 */#if ( portSTACK_GROWTH > 0 )StackType_t		*pxEndOfStack;		/*< 在堆栈从低内存向上增长架构中,指向堆栈的末端。 */#endif#if ( portCRITICAL_NESTING_IN_TCB == 1 )UBaseType_t		uxCriticalNesting;	/*< 对于不在端口层维护自身计数的端口,保存临界区嵌套深度。 */#endif#if ( configUSE_TRACE_FACILITY == 1 )UBaseType_t		uxTCBNumber;		/*< 存储一个每次创建TCB时递增的数字。它允许调试器确定任务何时被删除然后重新创建。 */UBaseType_t		uxTaskNumber;		/*< 存储一个专门供第三方跟踪代码使用的数字。 */#endif#if ( configUSE_MUTEXES == 1 )UBaseType_t		uxBasePriority;		/*< 最近分配给任务的优先级 - 用于优先级继承机制。 */UBaseType_t		uxMutexesHeld;#endif#if ( configUSE_APPLICATION_TASK_TAG == 1 )TaskHookFunction_t pxTaskTag;#endif#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 )void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ];#endif#if( configGENERATE_RUN_TIME_STATS == 1 )uint32_t		ulRunTimeCounter;	/*< 存储任务处于运行状态的时间量。 */#endif#if ( configUSE_NEWLIB_REENTRANT == 1 )/* 为该任务分配一个特定的新lib重入结构。注意:新lib支持是应大众需求而包含的,但FreeRTOS维护者自己并不使用。FreeRTOS不负责新lib的操作。用户必须熟悉新lib,并提供系统范围内必要的存根实现。请注意(在撰写时)当前新lib设计实现了一个需要锁定的系统范围malloc()。 */struct	_reent xNewLib_reent;#endif#if( configUSE_TASK_NOTIFICATIONS == 1 )volatile uint32_t ulNotifiedValue;volatile uint8_t ucNotifyState;#endif/* 参见tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE定义上方的注释。 */#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )uint8_t	ucStaticallyAllocated; 		/*< 如果任务是静态分配的,则设置为pdTRUE,以确保不会尝试释放内存。 */#endif#if( INCLUDE_xTaskAbortDelay == 1 )uint8_t ucDelayAborted;#endif} tskTCB;/* 旧的tskTCB名称在上方保持不变,然后typedef为新的TCB_t名称,以启用使用较旧的内核感知调试器。 */
typedef tskTCB TCB_t;

可以看出来FreeRTOS的任务控制块中的成员变量相比UCOSⅢ要少很多,而且大多数与
裁剪有关
,当不使用某些功能的时候与其相关的变量就不参与编译,任务控制块大小就会进一
步的减小。

六、任务堆栈

6.1 FreeRTOS任务堆栈管理

在FreeRTOS中,每个任务都有自己独立的堆栈空间,用来保存任务的上下文(包括CPU寄存器值等)。当任务被切换(即任务调度)时,当前任务的上下文会被保存在它自己的堆栈中。等到该任务再次运行时,它的上下文会从堆栈中恢复,从而任务可以继续执行之前中断的地方。这种机制是通过任务堆栈来实现的。

6.2 创建任务

FreeRTOS提供了两种创建任务的方法:动态方法和静态方法。

1. 动态方法:xTaskCreate():

xTaskCreate函数使用动态内存分配来创建任务包括任务堆栈和任务控制块(TCB)。

BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,const char * const pcName,configSTACK_DEPTH_TYPE usStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pxCreatedTask
);
  • pxTaskCode:任务函数。
  • pcName:任务名称。
  • usStackDepth:任务堆栈深度(即堆栈大小)。
  • pvParameters:传递给任务函数的参数。
  • uxPriority:任务优先级。
  • pxCreatedTask:任务句柄。

这个函数会自动分配和管理任务堆栈,用户不用自己定义堆栈。

2. 静态方法:xTaskCreateStatic()

xTaskCreateStatic函数使用静态内存来创建任务,这意味着用户需要自己提供任务堆栈和任务控制块(TCB)。

BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,const char * const pcName,configSTACK_DEPTH_TYPE usStackDepth,void *pvParameters,UBaseType_t uxPriority,TaskHandle_t *pxCreatedTask
);

每个参数的含义与xTaskCreate基本相同,不同的是: 

  • puxStackBuffer:指向用户定义的任务堆栈缓冲区。
  • pxTaskBuffer:指向用户定义的静态任务控制块(TCB)。

6.3 堆栈大小

在FreeRTOS中,任务堆栈的大小是以字节为单位指定的,而堆栈的数据类型 StackType_t 通常被定义为 uint32_t,这意味着每个堆栈单元占用4个字节。因此,当你在创建任务时指定堆栈大小(以 StackType_t 为单位),实际的堆栈大小(以字节为单位)确实是所指定大小的4倍。

例如,如果你使用 xTaskCreate()xTaskCreateStatic() 函数并指定堆栈大小为 100,那么实际的堆栈大小将是 100 * 4 = 400 字节。

任务堆栈用来保存任务现场(CPU寄存器值),创建任务的时候需要指定任务堆栈,任务堆栈的变量类型为StackType_t,此变量类型如下:

#define portSTACK_TYPE uint32_t
#define portBASE_TYPE longtypedef portSTACK_TYPE StackType_t;
typedef long BaseType_t;
typedef unsigned long UBaseType_t;
  1. #define portSTACK_TYPE uint32_t 定义了一个宏 portSTACK_TYPE,表示 uint32_t 类型。
  2. #define portBASE_TYPE long 定义了一个宏 portBASE_TYPE,表示 long 类型。
  3. typedef portSTACK_TYPE StackType_t; 使用 typedef 将 portSTACK_TYPE 定义为 StackType_t 类型。
  4. typedef long BaseType_t; 使用 typedef 将 long 定义为 BaseType_t 类型。
  5. typedef unsigned long UBaseType_t; 使用 typedef 将 unsigned long 定义为 UBaseType_t 类型。

 

 

📝大佬觉得本文有所裨益,不妨轻点一下👍给予鼓励吧!

❤️❤️❤️本人虽努力,但能力尚浅,若有不足之处,恳请各位大佬不吝赐教,您的批评指正将是我进步的动力!😊😊😊

💖💖💖若您认为此篇文章对您有所帮助,烦请点赞👍并收藏🌟,您的支持是我前行的最大动力!

🚀🚀🚀任务在默默中完成,价值在悄然间提升。让我们携手共进,一起加油,迎接更美好的未来!🌈🌈🌈

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode每日刷题之字符串相加(C++)

在学习的同时也不要忘记适当练习&#xff0c;本题字符串相加主要在于字符串类型与整数类型的转化&#xff0c;要将字符串类型转化为整数类型计算后转化为字符串类型输出即可。 思路解析 根据题中给出的信息&#xff0c;我们不可以使用库函数计算大整数&#xff0c;也不能直接将…

做空日经指数的策略与时机

一、市场背景分析 在全球股市的剧烈波动中&#xff0c;日本股市的表现尤为引人关注。日经225指数在经历一轮暴跌后&#xff0c;又出现了大幅反弹&#xff0c;这种剧烈的波动为投资者提供了做空日经指数的机会。近期&#xff0c;日本股市受到日元汇率波动、日本央行货币政策以及…

C++中的string的介绍(从string到STL)

C中的string的介绍 文章目录 C中的string的介绍1. 从string到STL2. string 的构造函数3. string 的iterator&#xff08;迭代器&#xff09;4. string 中的元素访问5. string 中容量相关6. string 中的插入删除7. string 中的查找8. string 的剩余函数 1. 从string到STL 严格来…

【轻松拿捏】Java是如何实现跨平台性的?

Java是如何实现跨平台性的&#xff1f; 一、Java 的跨平台性主要通过以下几个核心机制实现&#xff1a; 二、具体实现 三、示例 四、JVM 工作示意图 五、总结 &#x1f388;边走、边悟&#x1f388;迟早会好 一、Java 的跨平台性主要通过以下几个核心机制实现&#xff…

CICD流水线

一、CICD流水线简介 CICD概念 CI/CD流水线是现代软件开发的一个核心概念&#xff0c;它涉及自动化和管理软件从开发到部署的整个生命周期 概念定义 具体有三点&#xff1a;持续集成、持续交付、持续部署 流水线组成为&#xff1a;代码提交、测试、构建、部署、结果通知 二…

PHP最新可用获取QQ昵称API接口源码_非第三方

PHP最新可用获取QQ昵称API接口源码&#xff0c;运行环境为php7-8都可以&#xff0c;内容为直接调用QQ空间接口 在需要展示QQ昵称处&#xff0c;直接调用以下函数就可以。 例如&#xff1a;get_qq_nick(123456)就会直接输出123456的qq号昵称。 API源码下载&#xff1a;QQ昵称AP…

第R2周:LSTM-火灾温度预测:一文搞懂LSTM(长短期记忆网络)

一文搞懂LSTM&#xff08;长短期记忆网络&#xff09; 一句话介绍LSTM&#xff0c;它是RNN的进阶版&#xff0c;如果说RNN的最大限度是理解一句话&#xff0c;那么LSTM的最大限度则是理解一段话&#xff0c;详细介绍如下&#xff1a; LSTM&#xff0c;全称为长短期记忆网络(Lo…

python-鼠标绘画线条程序

闲来无聊简单编写了一个绘图小程序。 主要思路 主要是基于Python中的内置模块turtle编写的&#xff0c;简单扩展了一下&#xff0c;通过绑定事件能够达到鼠标绘制、删除、存储已经绘制图案的线条这几个功能。 路径结构 -draw- define.py- main.py- myturtle.py使用 点住鼠…

Element学习(入门)(1)

1、Element官网&#xff1a;https://element.eleme.cn/#/zh-CN 2、来源与用处 3、Element的快速入门 &#xff08;1&#xff09; &#xff08;2&#xff09;在入口文件&#xff08;main.js&#xff09;中引入 &#xff08;3&#xff09; 4、快捷键ctrlc&#xff0c;在当前的项目…

zsh 配置 docker 自动补全

zsh 配置 docker 自动补全 在终端中使用 docker 的命令的时候必须要全部手敲&#xff0c;没有提示&#xff0c;于是就在找是否有自动补全的脚本&#xff0c;搜索了一圈踩了一些坑总结了一下具体的步骤。 首先执行如下命令&#xff1a; mkdir -p ~/.zsh/completion curl -L h…

JavaEE: 查看线程信息

示例用代码 public class Main {static class MyThread extends Thread {Overridepublic void run() {while (true) {System.out.println("hello thread");try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}public st…

Python 用户输入和while循环

1、input()函数的工作原理&#xff08;用户输入&#xff09; input()函数让程序暂停运行&#xff0c;等待用户输入一些文本。获取用户输入后&#xff0c;Python将其赋给变量&#xff0c;以其使用。 在input()函数接受一个参数&#xff0c;既要向用户显示的提示&#xff0c;为了…

Linux 利用 ftrace 分析内核调用

目录 一、概述二、ftrace 的使用1、常用信息2、指定 ftrace 跟踪器3、设置要跟踪的函数4、ftrace 的开关5、function 跟踪程序6、function_graph 跟踪程序7、函数过滤器8、跟踪事件 三、trace-cmd 的使用1、常见命令2、常用选项2.1 列出可用的追踪器2.2 跟踪特定进程的函数调用…

计算机毕业设计选题推荐-课程教学平台-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

ceph

ceph是一个开源的&#xff0c;用c语言编写的分布式的存储系统。存储文件数据。 /dev/sdb fdisk /dev/sdb gdisk /dev/sdb lvm 逻辑卷 可以扩容 raid 磁盘 高可用 基于物理意义上的单机的存储系统。 分布式由多台物理磁盘组成一个集群&#xff0c;在这个基础之上实现高可…

激光导航AGV叉车那么多,究竟该怎么选?一篇文章讲明白~

AGV叉车 随着经济的快速发展&#xff0c;大部分企业的物料搬运开始脱离人工劳作&#xff0c;取而代之的是以叉车为主的机械化搬运。AGV叉车是工业搬运车辆&#xff0c;是指对成件托盘货物进行装卸、堆垛和短距离运输作业的各种轮式搬运车辆&#xff0c;主要应用于货场、工厂车间…

HslCommunicationDemo各品牌Plc通信测试软件工具

目录 1、HslCommunicationDemo程序包 2、ModbusTCP举例说明 (0)概述 &#xff08;1&#xff09;线圈写操作 &#xff08;2&#xff09;寄存器写操作 3、C#工程中DLL库文件使用 &#xff08;1&#xff09;创建Winform程序工程 &#xff08;2&#xff09;写寄存器 1、HslC…

基于内地城市生活垃圾收运场景的路线规划算法

基于混合遗传算法和模拟退火算法的优化垃圾收集路线规划 摘要 本文提出了一种基于混合遗传算法&#xff08;GA&#xff09;和模拟退火算法&#xff08;SA&#xff09;的创新路线规划方法&#xff0c;旨在优化内地城市的生活垃圾收集效率。算法结合了遗传算法的全局搜索能力和…

MySQL第1讲--详细安装教程和启动方法

文章目录 安装教程打开或关闭方式方式1&#xff1a;方式2&#xff1a; 客户端连接方式客户端连接方式1&#xff1a;客户端连接方式2&#xff1a;MySQL环境变量的配置 安装教程 1、mysql官网下载最新的符合本系统的版本 2、点击.msi文件进入安装页面 选择默认的选项开发者安…

15.DMDIS 工具优化

文章目录 前言一、安装部署安装数据源转换作业监控 二、性能优化问题 1 &#xff1a;DMETL 卡顿问题问题 2 &#xff1a;DM -> HIVE 的迁移速度慢问题 3 &#xff1a;ORACLE -> DM 的迁移速度慢问题 4 &#xff1a;GP -> DM 的迁移速度慢问题 5 &#xff1a;DM -> …