首页 > 其他分享 >FreeRTOS 4:任务相关数据结构

FreeRTOS 4:任务相关数据结构

时间:2024-10-27 21:52:41浏览次数:7  
标签:FreeRTOS LIST 列表 任务 用于 pxList 数据结构 INTEGRITY

任务相关数据结构

任务控制块TCB_t

FreeRTOS 的每个任务都有⼀些属性需要存储,FreeRTOS 把这些属性集合到⼀起⽤⼀个结构体来表⽰,这个结构体叫做任务控制块:TCB_t,在使⽤函数 xTaskCreate()创建任务的时候就会⾃动的给每个任务分配⼀个任务控制块。
此结构体在文件 tasks.c 中有定义。类似于 Linux 的 task_struct 结构体,保存进程信息⽤的,每个进程有⼀个。

typedef struct tskTaskControlBlock
{
    volatile StackType_t * pxTopOfStack; /* 指向任务栈上最后一个放置的项目的位置。这必须是TCB结构的第一个成员。 */

    #if ( portUSING_MPU_WRAPPERS == 1 )
        xMPU_SETTINGS xMPUSetting; /* MPU设置作为端口层的一部分定义。这必须是TCB结构的第二个成员。 */
    #endif

    ListItem_t xStateListItem;                  /* 任务的状态列表项所在的列表,表示任务的状态(就绪、阻塞、挂起)。 */
    ListItem_t xEventListItem;                  /* 用于从事件列表中引用任务。 */
    UBaseType_t uxPriority;                     /* 任务的优先级。0是最低优先级。 */
    StackType_t * pxStack;                      /* 指向栈的起始位置。 */
    char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任务创建时赋予的描述性名称,仅用于调试。 */

    #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) )
        StackType_t * pxEndOfStack; /* 指向栈的最高有效地址。 */
    #endif

    #if ( portCRITICAL_NESTING_IN_TCB == 1 )
        UBaseType_t uxCriticalNesting; /* 保存关键部分嵌套深度,用于不维护自己计数的端口。 */
    #endif

    #if ( configUSE_TRACE_FACILITY == 1 )
        UBaseType_t uxTCBNumber;  /* 由系统分配(每创建一个任务,值增加一),分配任务的值都不同,用于调试 */
        UBaseType_t uxTaskNumber; /* 由函数 vTaskSetTaskNumber()设置,用于调试 */
    #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 )
        struct  _reent xNewLib_reent; /* 为特定任务分配一个Newlib reent结构。 */
    #endif

    #if ( configUSE_TASK_NOTIFICATIONS == 1 )
        volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];/* 任务通知值 */
        volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ];/* 任务通知状态 */
    #endif

    #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 )
        uint8_t ucStaticallyAllocated; /* 如果任务是静态分配的,则设置为pdTRUE,以确保不会尝试释放内存。 */
    #endif

    #if ( INCLUDE_xTaskAbortDelay == 1 )
        uint8_t ucDelayAborted;/* 任务被中断延时标志 */
    #endif

    #if ( configUSE_POSIX_ERRNO == 1 )
        int iTaskErrno;/* 用于 POSIX */
    #endif
} tskTCB;

/* The old tskTCB name is maintained above then typedefed to the new TCB_t name
 * below to enable the use of older kernel aware debuggers. */
typedef tskTCB TCB_t;

tskTCB 的结构体,用于FreeRTOS操作系统中的任务控制块(Task Control Block)。每个任务在系统中都有一个对应的 tskTCB 实例,用于存储任务的各种状态和属性。具体包括:

  • 任务栈信息:指向任务栈的起始位置和栈顶位置。

  • 任务状态:通过 xStateListItem 和 xEventListItem 来记录任务的状态(如就绪、阻塞、挂起)。

  • 任务优先级:通过 uxPriority 来记录任务的优先级。

  • 任务名称:通过 pcTaskName 来记录任务的名称,主要用于调试。

  • 其他配置信息:根据编译选项,可能还包括MPU设置、关键部分嵌套深度、互斥信号量、任务标签、线程局部存储、运行时间统计、任务通知等。

  • 任务栈信息

    • pxTopOfStack:指向任务栈上最后一个放置的项目的位置。

    • pxStack:指向栈的起始位置。

    • pxEndOfStack(可选):指向栈的最高有效地址。

  • 任务状态

    • xStateListItem:任务的状态列表项,用于表示任务的状态(如就绪、阻塞、挂起)。

    • xEventListItem:用于从事件列表中引用任务。

  • 任务优先级

    • uxPriority:任务的优先级,0是最低优先级。

  • 任务名称

    • pcTaskName:任务创建时赋予的描述性名称,仅用于调试。

  • 其他配置信息

    • xMPUSetting(可选):MPU设置。

    • uxCriticalNesting(可选):保存关键部分嵌套深度。

    • uxTCBNumber 和 uxTaskNumber(可选):用于调试的任务编号。

    • uxBasePriority 和 uxMutexesHeld(可选):用于优先级继承机制。

    • pxTaskTag(可选):用户可自定义的任务钩子函数。

    • pvThreadLocalStoragePointers(可选):保存任务独有的数据。

    • ulRunTimeCounter(可选):存储任务处于运行状态的时间。

    • xNewLib_reent(可选):为特定任务分配一个Newlib reent结构。

    • ulNotifiedValue 和 ucNotifyState(可选):任务通知值和状态。

    • ucStaticallyAllocated(可选):标记任务是否静态分配。

    • ucDelayAborted(可选):任务被中断延时标志。

    • iTaskErrno(可选):用于POSIX的错误码。

列表 xLIST

列表和列表项是 FreeRTOS 的⼀个数据结构,FreeRTOS ⼤量使⽤到了列表和列表项, 它是 FreeRTOS 的基⽯。

列表被⽤来跟踪 FreeRTOS 中的任务。与列表相关的全部东⻄都在文件 list.c 和 list.h 中。在 list.h 中定义了⼀个叫 List_t 的结构体,如下:

/**
 * 定义结构体 xLIST 用于表示一个链表。
 * 
 * 成员变量说明:
 * - listFIRST_LIST_INTEGRITY_CHECK_VALUE: 
 *   当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。
 * - uxNumberOfItems: 表示链表中当前项目的数量。
 * - pxIndex: 用于遍历链表的指针,指向通过调用 listGET_OWNER_OF_NEXT_ENTRY() 返回的最后一个项目。
 * - xListEnd: 包含最大可能项目值的链表项,这意味着它总是位于链表的末尾,因此用作标记。
 * - listSECOND_LIST_INTEGRITY_CHECK_VALUE: 
 *   当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。
 */
typedef struct xLIST
{
    listFIRST_LIST_INTEGRITY_CHECK_VALUE          /*< 当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。 */
    volatile UBaseType_t uxNumberOfItems;
    ListItem_t * configLIST_VOLATILE pxIndex;     /*< 用于遍历链表的指针,指向通过调用 listGET_OWNER_OF_NEXT_ENTRY() 返回的最后一个项目。 */
    MiniListItem_t xListEnd;                      /*< 包含最大可能项目值的链表项,这意味着它总是位于链表的末尾,因此用作标记。 */
    listSECOND_LIST_INTEGRITY_CHECK_VALUE         /*< 当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。 */
} List_t;

1. 在该结构体中, 包含了两个宏,分别为 listFIRST_LIST_INTEGRITY_CHECK_VALUE 和listSECOND_LIST_INTEGRITY_CHECK_VALUE,这两个宏用于存放确定已知常量, FreeRTOS通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏,类似这样的宏定义在列表项和迷你列表项中也有出现。该功能一般用于调试, 默认是不开启的,因此本教程暂不讨论这个功能。
2. 成员变量 uxNumberOfItems 用于记录列表中列表项的个数(不包含 xListEnd),当往列表中插入列表项时,该值加 1;当从列表中移除列表项时,该值减 1。
3. 成员变量 pxIndex 用于指向列表中的某个列表项,一般用于遍历列表中的所有列表项。
4. 成员变量 xListEnd 是一个迷你列表项, 列表中迷你列表项的值一般被设置为最大值,用于将列表中的所有列表项按升序排序时,排在最末尾;同时 xListEnd 也用于挂载其他插入到列表中的列表项。

列表的结构示意图,如下图所示:

列表项ListItem_t

列表项就是存放在列表中的项⽬,FreeRTOS 提供了两种列表项:列表项和迷你列表项。这 两个都在文件 list.h中有定义,先来看⼀下列表项,定义如下:

/**
 * 结构体 xLIST_ITEM 用于表示链表中的一个节点。
 * 
 * 成员变量说明:
 * - xItemValue: 被列出的值。通常用于按降序对链表进行排序。
 * - pxNext: 指向链表中下一个节点的指针。
 * - pxPrevious: 指向链表中前一个节点的指针。
 * - pvOwner: 指向包含该链表项的对象(通常是任务控制块TCB)的指针。因此,对象和链表项之间存在双向链接。
 * - pxContainer: 指向该链表项所属的链表(如果有)的指针。
 * - listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE 和 listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE: 
 *   当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,这些字段将被设置为已知值,用于数据完整性检查。
 */
struct xLIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE
    configLIST_VOLATILE TickType_t xItemValue;
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
    void * pvOwner;
    struct xLIST * configLIST_VOLATILE pxContainer;
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE
};

/**
 * 定义别名 ListItem_t 为结构体 xLIST_ITEM。
 * 
 * 注:lint 工具要求将其定义为两个独立的声明。
 */
typedef struct xLIST_ITEM ListItem_t;ct xLIST_ITEM ListItem_t;                       /* For some reason lint wants this as two separate definitions. */

1. 如同列表一样,列表项中也包含了两个用于检测列表项数据完整性的宏定义。
2. 成员变量 xItemValue 为列表项的值,这个值多用于按升序对列表中的列表项进行排序。
3. 成员变量 pxNext 和 pxPrevious 分别用于指向列表中列表项的下一个列表项和上一个列
表项。
4. 成员变量 pxOwner 用于指向包含列表项的对象(通常是任务控制块),因此,列表项和包含列表项的对象之间存在双向链接。
5. 成员变量 pxContainer 用于指向列表项所在列表。
列表项的结构示意图,如下图所示:

迷你列表项MiniListItem_t

迷你列表项在文件 list.h 中有定义。

/**
 * 定义结构体 xMINI_LIST_ITEM 用于表示一个简化版的链表项。
 * 
 * 成员变量说明:
 * - listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE: 
 *   当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。
 * - xItemValue: 被列出的值。通常用于按降序对链表进行排序。
 * - pxNext: 指向链表中下一个节点的指针。
 * - pxPrevious: 指向链表中前一个节点的指针。
 */
struct xMINI_LIST_ITEM
{
    listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE     /*< 当 configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 设置为 1 时,此字段将被设置为已知值,用于数据完整性检查。 */
    configLIST_VOLATILE TickType_t xItemValue;
    struct xLIST_ITEM * configLIST_VOLATILE pxNext;
    struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
};

/**
 * 定义别名 MiniListItem_t 为结构体 xMINI_LIST_ITEM。
 */
typedef struct xMINI_LIST_ITEM MiniListItem_t;

1. 迷你列表项中也同样包含用于检测列表项数据完整性的宏定义。
2. 成员变量 xItemValue 为列表项的值,这个值多用于按升序对列表中的列表项进行排序。
3. 成员变量 pxNext 和 pxPrevious 分别用于指向列表中列表项的下一个列表项和上一个列表项。
4. 迷你列表项相比于列表项,因为只用于标记列表的末尾和挂载其他插入列表中的列表项,
因此不需要成员变量 pxOwner 和 pxContainer,以节省内存开销。

有些情况下我们不需要列表项这么全的功能,可能只需要其中的某⼏个成员变量,如果此时⽤列表项的话会造成内存浪费!比如上⾯列表结构体 List_t 中表⽰最后⼀个列表项的成员变量 xListEnd 就是MiniListItem_t 类型的。

迷你列表项的结构示意图,如下图所示:

不同状态任务定义

PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /*< Prioritised ready tasks. */
PRIVILEGED_DATA static List_t xDelayedTaskList1;                         /*< Delayed tasks. */
PRIVILEGED_DATA static List_t xDelayedTaskList2;                         /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;              /*< Points to the delayed task list currently being used. */
PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;      /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
PRIVILEGED_DATA static List_t xPendingReadyList;                         /*< Tasks that have been readied while the scheduler was suspended.  They will be moved to the ready list when the scheduler is resumed. */

高优先级的任务可以像中断的抢占一样,抢占低优先级任务的 CPU 使用权;优先级相同的任务则各自轮流运行一段极短的时间(宏观角度),从而产生“同时”运行的错觉。

列表和列表项相关函数

FreeRTOS 中列表和列表项相关的 API 函数如下表所示:

函数 vListInitialise()

此函数用于初始化列表,在定义列表之后,需要先对其进行初始化, 只有初始化后的列表,才能够正常地被使用。列表初始化的过程,其实就是初始化列表中的成员变量。 函数原型如下所示:

void vListInitialise(List_t * const pxList); 

void vListInitialise(
	List_t * const pxList)
{
	/* 初始化时,列表中只有 xListEnd,因此 pxIndex 指向 xListEnd */
	pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd );
	/* xListEnd 的值初始化为最大值,用于列表项升序排序时,排在最后 */
	pxList->xListEnd.xItemValue = portMAX_DELAY;
	/* 初始化时,列表中只有 xListEnd,因此上一个和下一个列表项都为 xListEnd 本身 */
	pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );
	pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );
	/*初始化时,列表中的列表项数量为 0(不包含 xListEnd) */
	pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
	/* 初始化用于检测列表数据完整性的校验值 */
	listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
	listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );		
}

函数 vListInitialise()初始化后的列表结构示意图, 如下图所示:

函数 vListInitialiseItem()

如同列表一样,在定义列表项之后,也需要先对其进行初始化,只有初始化有的列表项,才能够被正常地使用。列表项初始化的过程,也是初始化列表项中的成员变量。 函数原型如下所示:

void vListInitialiseItem(ListItem_t * const pxItem); 

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

void vListInitialiseItem(
	ListItem_t * const pxItem)
{
	/* 初始化时,列表项所在列表设为空 */
	pxItem->pxContainer = NULL;
	/* 初始化用于检测列表项数据完整性的校验值 */
	listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
	listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

这个函数比较简单,只需将列表项所在列表设置为空,以保证列表项不再任何一个列表项中即可。函数 vListInitialiseItem()初始化后的列表项结构示意图, 如下图所示:

函数 vListInsertEnd()

此函数用于将待插入列表的列表项插入到列表 pxIndex 指针指向列表项的前面,是一种无序的插入方法。 函数原型如下所示:

void vListInsertEnd(
	List_t * const pxList,
		ListItem_t * const pxNewListItem);

--javascripttypescriptshellbashsqljsonhtmlcssccppjavarubypythongorustmarkdown

void vListInsertEnd(
	List_t * const pxList,
		ListItem_t * const pxNewListItem)
{
	/* 获取列表 pxIndex 指向的列表项 */
	ListItem_t * const pxIndex = pxList->pxIndex;
	/* 检查参数是否正确 */
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
	/* 更新待插入列表项的指针成员变量 */
	pxNewListItem->pxNext = pxIndex;
	pxNewListItem->pxPrevious = pxIndex->pxPrevious;
		/* 测试使用,不用理会 */
	mtCOVERAGE_TEST_DELAY();
	/* 更新列表中原本列表项的指针成员变量 */
	pxIndex->pxPrevious->pxNext = pxNewListItem;
	pxIndex->pxPrevious = pxNewListItem;
	/* 更新待插入列表项的所在列表成员变量 */
	pxNewListItem->pxContainer = pxList;
	/* 更新列表中列表项的数量 */
	( pxList->uxNumberOfItems )++;
}

此函数就是将待插入的列表项插入到列表 pxIndex 指向列表项的前面,要注意的时, pxIndex 不一定指向 xListEnd,而是有可能指向列表中任意一个列表项。函数 vListInsertEnd()插入列表项后的列表结构示意图,如下图所示:

函数 vListInsert()

此函数用于将待插入列表的列表项按照列表项值升序排序的顺序,有序地插入到列表中。函数原型如下所示:

void vListInsert(List_t * const pxList,ListItem_t * const pxNewListItem); 

void vListInsert(
	List_t * const pxList,
	ListItem_t * const pxNewListItem)
{
	ListItem_t * pxIterator;
	const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
	/* 检查参数是否正确 */
	listTEST_LIST_INTEGRITY( pxList );
	listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
	/* 如果待插入列表项的值为最大值 */
	if( xValueOfInsertion == portMAX_DELAY )
	{
		/* 插入的位置为列表 xListEnd 前面 */
		pxIterator = pxList->xListEnd.pxPrevious;
	}
	else
	{
		/* 遍历列表中的列表项,找到插入的位置 */
		for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd );
			pxIterator->pxNext->xItemValue <= xValueOfInsertion;
				pxIterator = pxIterator->pxNext )
		{ 
		}
	}
	/* 将待插入的列表项插入指定位置 */
	pxNewListItem->pxNext = pxIterator->pxNext;
	pxNewListItem->pxNext->pxPrevious = pxNewListItem;
	pxNewListItem->pxPrevious = pxIterator;
	pxIterator->pxNext = pxNewListItem;
	/* 更新待插入列表项所在列表 */
	pxNewListItem->pxContainer = pxList;
	/* 更新列表中列表项的数量 */
	( pxList->uxNumberOfItems )++;
}

此函数在将待插入列表项插入列表之前,会前遍历列表,找到待插入列表项需要插入的位置。待插入列表项需要插入的位置是依照列表中列表项的值按照升序 排序确定的。函数 vListInsert()插入列表项后的列表结构示意图,如下图所示:

函数 uxListRemove()

此函数用于将列表项从列表项所在列表中移除,函数原型如下所示:

UBaseType_t uxListRemove(ListItem_t * const pxItemToRemove); 



UBaseType_t uxListRemove(
ListItem_t * const pxItemToRemove)
{
	List_t * const pxList = pxItemToRemove->pxContainer;
	/* 从列表中移除列表项 */
	pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
	pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
	/* 测试使用,不用理会 */
	mtCOVERAGE_TEST_DELAY();
	/* 如果 pxIndex 正指向待移除的列表项 */
	if( pxList->pxIndex == pxItemToRemove )
	{
		/* pxIndex 指向上一个列表项 */
		pxList->pxIndex = pxItemToRemove->pxPrevious;
	}
	else
	{
		mtCOVERAGE_TEST_MARKER();
	}
	/* 将待移除列表项的所在列表指针清空 */
	pxItemToRemove->pxContainer = NULL;
	/* 更新列表中列表项的数量 */
	( pxList->uxNumberOfItems )--;
	/* 返回列表项移除后列表中列表项的数量 */
	return pxList->uxNumberOfItems;
}

函数 uxListRemove()移除后的列表项,依然于列表有着单向联系,即移除后列表项中用于指向上一个和下一个列表项的指针,依然指向列表中的列表项。 函数 uxListRemove()移除列表项后的列表结构示意图,如下图所示:

标签:FreeRTOS,LIST,列表,任务,用于,pxList,数据结构,INTEGRITY
From: https://blog.csdn.net/weixin_52849254/article/details/143262449

相关文章

  • 团队任务2-《需求规格说明书》
    需求规格说明书这个作业属于哪个课程https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/这个作业要求在哪里https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13232这个作业的目标通过需求分析制定需求规格说明书,熟悉git协助方式1.需求规格说明书......
  • FreeRTOS同步互斥与通信(有缺陷的同步示例,有缺陷的互斥示例)
    同步互斥1.同步同步指的是协调多个线程或进程的执行顺序,以确保某些操作按预期的顺序进行。同步主要用于解决依赖关系的问题,确保线程之间的协调。目的:保证操作的顺序,确保某些条件成立前不进行后续操作。实现方式:信号量:控制访问共享资源的数量,可以限制同时访问的线......
  • Python基础入门——Python数据结构
    前言1.List(列表)原理列表是一种有序的可变容器,可以存储任意类型的对象。它的主要操作包括索引、切片、添加、删除、修改元素等。列表中的元素在内存中是连续存储的(对于简单的对象,如整数、字符串等是这样,对于复杂对象可能涉及到引用的存储),这使得通过索引访问元素的速度非......
  • 计划任务管理
    计划任务管理at;crontabat:一次性计划任务at是一个用于在指定时间运行一次性命令的Linux工具。1.基本语法at[选项]时间2.时间格式at支持多种时间格式,常见的包括:指定的日期和时间:at10:00:在当天的10:00运行。at15:3010/31:在10月31日的15:30运行。......
  • 数据结构知识点总结[导师教案版]
    绪论内容提要:◆数据结构研究的内容。针对非数值计算的程序设计问题,研究计算机的操作对象以及它们之间的关系和操作。数据结构涵盖的内容: ◆基本概念:数据、数据元素、数据对象、数据结构、数据类型、抽象数据类型。数据——所有能被计算机识别、存储和处理的符号的......
  • 数据结构与算法分析:你真的理解排序算法吗——总结
    一、选择排序算法的标准选择一个排序算法时,考虑下表的定性标准。这些标准可能能够帮你做出最初的决定,但是你需要更多量化标准作为指引。在为不同的数据选择合适的算法的时候,你需要知道输入数据的一些性质。我们创建了一些基准测试数据来比较本章所讲述的算法。注意表中的......
  • java数据结构
    Java提供了丰富的数据结构来处理和组织数据。Java的java.util包中提供了许多这些数据结构的实现,可以根据需要选择合适的类。以下是一些常见的Java数据结构:数组(Array):数组(Arrays)是一种基本的数据结构,可以存储固定大小的相同类型的元素。int[]array=newint[5];特......
  • 如何使用Cron在Linux上安排定时任务
    使用Cron在Linux上安排定时任务的步骤:1.为任务分类,选择代表性的任务;2.设定明确的目标,确定任务的执行时间;3.选择适当的调研形式;4.安排任务的执行顺序;5.深入研究任务的需求。首先,与用户调研中为用户归类选择代表性用户一样,我们需要为任务归类并选择代表性的任务。1.为任务分类,选......
  • 数据结构:“小猫钓鱼游戏”
    一:题目栈和队列的综合应用:“小猫钓鱼”的游戏规则是:将一副扑克牌平均分成两份,每人拿一份。玩家甲先拿出手中的第一张扑克牌放在桌上,然后玩家乙也拿出手中的第一张扑克牌,并放在玩家甲刚打出的扑克牌的上面,就像这样两个玩家交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌......
  • 数据结构~红黑树
    文章目录一、红黑树的概念二、红黑树的定义三、红黑树的插入四、红黑树的平衡五、红黑树的验证六、红黑树的删除七、完整代码八、总结一、红黑树的概念红黑树是一棵二叉搜索树,他的每个结点增加⼀个存储位来表示结点的颜色,可以是红色或者黑色。通过对任何⼀条从根到......