目录
一、线程简介
二、线程的创建
三、操作双向链表
3.1、初始化节点链表
3.2、在双向链表表头后插入一个节点
?3.3、双向链表尾部插入一个节点
?3,4、从双向链表中删除一个节点
一、线程简介
在多线程系统中我们根据功能的不同,把系统分为一个个独立的且无法返回的函数。此函数称为线程。
void DoSomeThing(void){
// 线程主体无限循环,且无法返回
while(1){
// 线程主体代码
}
}
二、线程的创建
- 裸机系统中的全局变量,局部变量都存放在栈中。
- 栈:单片机 RAM 里面一段连续的内存空间,栈的大小一般在启动文件或者链接脚本里 面指定,最后由 C 库函数_main 进行初始化。
- 多线程中每个线程都是独立且互不干扰的,因此要为每个线程分配独立的栈空间。
- 栈空间:预先定义的全局数组、动态分配的一段内存(存在于RAM中)都是栈空间。
三、操作双向链表
// 条件编译
#ifdef __CC_ARM
#define rt_inline static __inline
#define ALIGN(n) __attribute__((aligned(n)))
#elif defined(__IAR_SYSTEMS_ICC__)
#define rt_inline static inline
#define ALIGN(n) PRAGMA(data_alignment=n)
#elif defined (__GNUC__)
#define rt_inline static __inline
#define ALIGN(n) __attribute__((aligned(n)))
#else
#error not supported tool chain
#endif
// 线程结构体
struct rt_thread {
void *sp; /* 线程栈指针 */
void *entry; /* 线程入口地址 */
void *parameter; /* 线程形参 */
void *stack_addr; /* 线程起始地址 */
rt_uint32_t stack_size; /* 线程栈大小,单位为字节 */
rt_list_t tlist; /* 线程链表节点 */
};
typedef struct rt_thread *rt_thread_t; // 结构体别名
// 双向链表结构体
truct rt_list_node {
struct rt_list_node *next; /* 指向后一个节点 */
struct rt_list_node *prev; /* 指向前一个节点 */
};
typedef struct rt_list_node rt_list_t;
3.1、初始化节点链表
// 初始化链表节点
rt_inline void rt_list_init(rt_list_t *l)
{
// 初始表头下一个和上一个都指向自己
l->next = l->prev=l;
}
3.2、在双向链表表头后插入一个节点
rt_inline void rt_list_insert_after(rt_list_t *l,rt_list_t *n)
{
// rt_list_t:节点的数据类型 l:节点名称
// next:节点指针,指向链表中的下一个节点
// prev:节点指针,指向链表中的上一个节点
// 序号1
l->next->prev=n; // 插入节点时 原链表表头后一个节点的prev(钩子方向)就是要插入的节点
// 序号2
n->next=l->next; // 插入节点时 要插入的节点(n)的下一个节点是原链表中表头的后一个节点
// 序号3
l->next =n; // 插入后 链表头节点(l)下一个节点是要插入的节点(n)
// 序号4
n->prev =l; // 插入后 新插入的节点(n)的上一个节点为链表头节点(l)
}
?3.3、双向链表尾部插入一个节点
// 双向链表表头前面插入一个节点(双向链表尾部插入节点)
rt_inline void rt_list_insert_before(rt_list_t *l,rt_list_t *n)
{
// 插入节点时,原链表表头前一个节点(原链表尾节点)的next就是要插入的节点(n)。
l->prev->next=n; // 序号1
// 插入节点时,要插入的节点的上一个节点是原链表表头的上一个节点。
n->prev=l->prev; // 序号2
// 插入后,链表的前一个节点为要插入的节点。
l->prev = n; // 序号3
// 插入后,插入的节点的后一个节点为链表表头节点。
n->next =l; // 序号4
}
?3,4、从双向链表中删除一个节点
// 从双向链表中删除一个节点
rt_inline void rt_list_remove(rt_list_t *n)
{
// 删除节点n时,删除节点n的节点指针prev,prev指向n的上一个节点
n->next->prev=n->prev; // 序号1
// 删除节点n时,删除节点n的节点指针next,next指向n的下一个节点
n->prev->next=n->next; // 序号2
// 删除n节点后,节点指针next与节点指针prev指向节点n本身
n->next = n->prev=n; // 序号3
}
|