xref: /nrf52832-nimble/rt-thread/examples/kernel/thread_delete.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  * 程序清单:删除线程
3  *
4  * 这个例子会创建两个线程,在一个线程中删除另外一个线程。
5  */
6 #include <rtthread.h>
7 #include "tc_comm.h"
8 
9 /*
10  * 线程删除(rt_thread_delete)函数仅适合于动态线程,为了在一个线程
11  * 中访问另一个线程的控制块,所以把线程块指针声明成全局类型以供全
12  * 局访问
13  */
14 static rt_thread_t tid1 = RT_NULL, tid2 = RT_NULL;
15 /* 线程1的入口函数 */
thread1_entry(void * parameter)16 static void thread1_entry(void* parameter)
17 {
18     rt_uint32_t count = 0;
19 
20     while (1)
21     {
22         /* 线程1采用低优先级运行,一直打印计数值 */
23         // rt_kprintf("thread count: %d\n", count ++);
24         count ++;
25     }
26 }
thread1_cleanup(struct rt_thread * tid)27 static void thread1_cleanup(struct rt_thread *tid)
28 {
29     if (tid != tid1)
30     {
31         tc_stat(TC_STAT_END | TC_STAT_FAILED);
32         return ;
33     }
34     rt_kprintf("thread1 end\n");
35     tid1 = RT_NULL;
36 }
37 
38 /* 线程2的入口函数 */
thread2_entry(void * parameter)39 static void thread2_entry(void* parameter)
40 {
41     /* 线程2拥有较高的优先级,以抢占线程1而获得执行 */
42 
43     /* 线程2启动后先睡眠10个OS Tick */
44     rt_thread_delay(RT_TICK_PER_SECOND);
45 
46     /*
47      * 线程2唤醒后直接删除线程1,删除线程1后,线程1自动脱离就绪线程
48      * 队列
49      */
50     rt_thread_delete(tid1);
51 
52     /*
53      * 线程2继续休眠10个OS Tick然后退出,线程2休眠后应切换到idle线程
54      * idle线程将执行真正的线程1控制块和线程栈的删除
55      */
56     rt_thread_delay(RT_TICK_PER_SECOND);
57 }
58 
thread2_cleanup(struct rt_thread * tid)59 static void thread2_cleanup(struct rt_thread *tid)
60 {
61     /*
62      * 线程2运行结束后也将自动被删除(线程控制块和线程栈在idle线
63      * 程中释放)
64      */
65 
66     if (tid != tid2)
67     {
68         tc_stat(TC_STAT_END | TC_STAT_FAILED);
69         return ;
70     }
71     rt_kprintf("thread2 end\n");
72     tid2 = RT_NULL;
73     tc_done(TC_STAT_PASSED);
74 }
75 
76 /* 线程删除示例的初始化 */
thread_delete_init()77 int thread_delete_init()
78 {
79     /* 创建线程1 */
80     tid1 = rt_thread_create("t1", /* 线程1的名称是t1 */
81         thread1_entry, RT_NULL,   /* 入口是thread1_entry,参数是RT_NULL */
82         THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
83     if (tid1 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
84     {
85         tid1->cleanup = thread1_cleanup;
86         rt_thread_startup(tid1);
87     }
88     else
89         tc_stat(TC_STAT_END | TC_STAT_FAILED);
90 
91     /* 创建线程1 */
92     tid2 = rt_thread_create("t2", /* 线程1的名称是t2 */
93         thread2_entry, RT_NULL,   /* 入口是thread2_entry,参数是RT_NULL */
94         THREAD_STACK_SIZE, THREAD_PRIORITY - 1, THREAD_TIMESLICE);
95     if (tid2 != RT_NULL) /* 如果获得线程控制块,启动这个线程 */
96     {
97         tid2->cleanup = thread2_cleanup;
98         rt_thread_startup(tid2);
99     }
100     else
101         tc_stat(TC_STAT_END | TC_STAT_FAILED);
102 
103     return 10 * RT_TICK_PER_SECOND;
104 }
105 
106 #ifdef RT_USING_TC
_tc_cleanup()107 static void _tc_cleanup()
108 {
109     /* lock scheduler */
110     rt_enter_critical();
111 
112     /* delete thread */
113     if (tid1 != RT_NULL)
114     {
115         rt_kprintf("tid1 is %p, should be NULL\n", tid1);
116         tc_stat(TC_STAT_FAILED);
117     }
118     if (tid2 != RT_NULL)
119     {
120         rt_kprintf("tid2 is %p, should be NULL\n", tid2);
121         tc_stat(TC_STAT_FAILED);
122     }
123 
124     /* unlock scheduler */
125     rt_exit_critical();
126 }
127 
_tc_thread_delete()128 int _tc_thread_delete()
129 {
130     /* set tc cleanup */
131     tc_cleanup(_tc_cleanup);
132     return thread_delete_init();
133 }
134 FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
135 #else
rt_application_init()136 int rt_application_init()
137 {
138     thread_delete_init();
139 
140     return 0;
141 }
142 #endif
143