1. 线程创建
线程的创建可以使用rt_thread_create()函数,原型如下:
rt_thread_t rt_thread_create(const char *name,
void (*entry)(void *parameter),
void *parameter,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick);
线程创建成功后将返回线程句柄,否则返回RT_NULL。
例如:
/*
* 程序清单:动态线程
*
* 这个程序会初始化2个动态线程:
* 它们拥有共同的入口函数,相同的优先级
* 但是它们的入口参数不相同
*/
#include
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
/* 指向线程控制块的指针 */
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得线程的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
/* 用户应用入口 */
int rt_application_init()
{
/* 创建线程1 */
tid1 = rt_thread_create("t1",
thread_entry, (void*)1, /* 线程入口是thread_entry, 入口参数是1 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
else
return -1;
/* 创建线程2 */
tid2 = rt_thread_create("t2",
thread_entry, (void*)2, /* 线程入口是thread_entry, 入口参数是2 */
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
else
return -1;
return 0;
}
线程的创建有时可能还会用到另外一个函数,那就是rt_thread_init(),原型如下:
rt_err_t rt_thread_init(struct rt_thread *thread,
const char *name,
void (*entry)(void *parameter),
void *parameter,
void *stack_start,
rt_uint32_t stack_size,
rt_uint8_t priority,
rt_uint32_t tick);
例如:
/*
* 程序清单:初始化静态线程
*
* 这个程序会初始化2个静态线程,它们拥有共同的入口函数,但参数不相同
*/
#include
#define THREAD_PRIORITY 25
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 5
/* 线程1控制块 */
static struct rt_thread thread1;
/* 线程1栈 */
ALIGN(4)
static rt_uint8_t thread1_stack[THREAD_STACK_SIZE];
/* 线程2控制块 */
static struct rt_thread thread2;
/* 线程2栈 */
ALIGN(4)
static rt_uint8_t thread2_stack[THREAD_STACK_SIZE];
/* 线程入口 */
static void thread_entry(void* parameter)
{
rt_uint32_t count = 0;
rt_uint32_t no = (rt_uint32_t) parameter; /* 获得正确的入口参数 */
while (1)
{
/* 打印线程计数值输出 */
rt_kprintf("thread%d count: %d\n", no, count ++);
/* 休眠10个OS Tick */
rt_thread_delay(10);
}
}
/* 用户应用入口 */
int rt_application_init()
{
rt_err_t result;
/* 初始化线程1 */
result = rt_thread_init(&thread1, "t1", /* 线程名:t1 */
thread_entry, (void*)1, /* 线程的入口是thread_entry,入口参数是1 */
&thread1_stack[0], sizeof(thread1_stack), /* 线程栈是thread1_stack */
THREAD_PRIORITY, 10);
if (result == RT_EOK) /* 如果返回正确,启动线程1 */
rt_thread_startup(&thread1);
else
return -1;
/* 初始化线程2 */
result = rt_thread_init(&thread2, "t2", /* 线程名:t2 */
thread_entry, (void*)2, /* 线程的入口是thread_entry,入口参数是2 */
&thread2_stack[0], sizeof(thread2_stack), /* 线程栈是thread2_stack */
THREAD_PRIORITY + 1, 10);
if (result == RT_EOK) /* 如果返回正确,启动线程2 */
rt_thread_startup(&thread2);
else
return -1;
return 0;
}
那么rt_thread_create()和rt_thread_init()有什么区别呢?
使用rt_thread_create()函数线程句柄和栈空间是从系统堆栈中动态分配的,而使用rt_thread_init()函数线程句柄和栈空间是静态分配的,也就是说一个由系统动态分配,一个由用户自己分配。
2. 线程启动
不管是rt_thread_create()、还是rt_thread_init()创建的线程,线程的状态都处于初始态,线程并未被调度。
需要调用rt_thread_startup()函数,这样线程的状态也由初始态变为就绪态,线程才能被调度,原型如下:
rt_err_t rt_thread_startup(rt_thread_t thread);
3. 线程睡眠
有的时候需要让当前运行的线程延时一段时间,需要用到下面两个函数:
rt_err_t rt_thread_sleep(rt_tick_t tick);
rt_err_t rt_thread_delay(rt_tick_t tick);
注意1:是睡眠延时。
注意2:rt_thread_sleep()在最新代码中没有找到相关接口。
线程相关内容更多请参考: https://www.rt-thread.org/document/site/zh/1chapters/02-chapter_thread/