前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zephyr笔记 2.1.1 线程的生命周期

zephyr笔记 2.1.1 线程的生命周期

作者头像
twowinter
发布2020-04-17 10:28:53
1.3K0
发布2020-04-17 10:28:53
举报
文章被收录于专栏:twowinter

1 前言

这节将会描述线程的创建,调度以及删除操作。

http://docs.zephyrproject.org/kernel/threads/lifecycle.html

2 概念

概念不复制了。

3 操作

3.1 Spawning a Thread

线程的创建,是通过定义它的栈区域,以及它的线程控制块,之后调用 k_thread_create()。其中的栈区域是通过 K_THREAD_STACK_DEFINE 来定义,保证在内存中建立起区域。

线程创建函数将会返回它的线程id,以此来对应线程。

如下是示例代码:

代码语言:javascript
复制
#define MY_STACK_SIZE 500
#define MY_PRIORITY 5

extern void my_entry_point(void *, void *, void *);

K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE);
struct k_thread my_thread_data;

k_tid_t my_tid = k_thread_create(&my_thread_data, my_stack_area,
                                 K_THREAD_STACK_SIZEOF(my_stack_area),
                                 my_entry_point,
                                 NULL, NULL, NULL,
                                 MY_PRIORITY, 0, K_NO_WAIT);

Alternatively, a thread can be spawned at compile time by calling K_THREAD_DEFINE. Observe that the macro defines the stack area, control block, and thread id variables automatically. 或者,线程可以在编译时间通过调用 K_THREAD_DEFINE 来创建,栈区域、控制块、线程id都自动创建。

如下代码和上面的代码是一样的:

代码语言:javascript
复制
#define MY_STACK_SIZE 500
#define MY_PRIORITY 5

extern void my_entry_point(void *, void *, void *);

K_THREAD_DEFINE(my_tid, MY_STACK_SIZE,
                my_entry_point, NULL, NULL, NULL,
                MY_PRIORITY, 0, K_NO_WAIT);

用户模式限制

这节仅适用于 CONFIG_USERSPACE 使能,用户线程想要创建新线程的情况。仍可以使用 k_thread_create() API,但有一些额外的限制需要注意下,否则调用会被停止:

  • The calling thread must have permissions granted on both the child thread and stack parameters; both are tracked by the kernel as kernel objects.
  • The child thread and stack objects must be in an uninitialized state, i.e. it is not currently running and the stack memory is unused.
  • The stack size parameter passed in must be equal to or less than the bounds of the stack object when it was declared.
  • The K_USER option must be used, as user threads can only create other user threads.
  • The K_ESSENTIAL option must not be used, user threads may not be considered essential threads.
  • The priority of the child thread must be a valid priority value, and equal to or lower than the parent thread.

3.2 Dropping Permissions

代码语言:javascript
复制
If CONFIG_USERSPACE is enabled, a thread running in supervisor mode may perform a one-way transition to user mode using the k_thread_user_mode_enter() API. This is a one-way operation which will reset and zero the thread’s stack memory. The thread will be marked as non-essential.

3.3 终止线程

线程可以从自己的 entry point 函数中返回,即可终止线程。

如下代码展示如何终止线程。

代码语言:javascript
复制
void my_entry_point(int unused1, int unused2, int unused3)
{
    while (1) {
        ...
        if (<some condition>) {
            return; /* thread terminates from mid-entry point function */
        }
        ...
    }

    /* thread terminates at end of entry point function */
}

如果 CONFIG_USERSPACE 使能,终止一个线程将会标记线程和栈为未初始化,以方便他们再次使用。

4 建议用法

使用线程来处理那些不能在ISR的事务。

使用分开的线程来处理逻辑上分开又可以并行的操作。

5 配置选项

  • CONFIG_USERSPACE

6 API

下列线程API,都在 kernel.h 中提供了:

K_THREAD_DEFINE k_thread_create() k_thread_cancel() k_thread_abort() k_thread_suspend() k_thread_resume() K_THREAD_STACK_DEFINE K_THREAD_STACK_ARRAY_DEFINE K_THREAD_STACK_MEMBER K_THREAD_STACK_SIZEOF K_THREAD_STACK_BUFFER

End

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 前言
  • 2 概念
  • 3 操作
    • 3.1 Spawning a Thread
      • 3.2 Dropping Permissions
        • 3.3 终止线程
        • 4 建议用法
        • 5 配置选项
        • 6 API
        • End
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档