1. completion 是什么
completion 直接翻譯過來是完成,所以我們可以稱 rt_completion 為 完成量。在 RT-Thread 的文檔中心 中講線程間同步時,介紹了 信號量, 互斥量, 事件集 。 rt_completion 是一個 輕量級的二值信號量。
2. completion 怎么使用
completion 的使用非常簡單
定義一個完成量
1struct rt_completion completion;
初始化完成量
1rt_completion_init(&completion);
等待完成量
1rt_completion_wait(&completion);
釋放完成量
《br /》rt_completion_done(&completion);《br /》
3. completion 的實現
completion 的 API 非常少,可以通過簡單的代碼去分析
初始化完成量
1void rt_completion_init(struct rt_completion *completion)
2{
3 rt_base_t level;
4 RT_ASSERT(completion != RT_NULL);
5
6 level = rt_hw_interrupt_disable();
7 completion-》flag = RT_UNCOMPLETED;
8 rt_list_init(&completion-》suspended_list);
9 rt_hw_interrupt_enable(level);
10}
干了兩件事:
設置 flag 為 RT_UNCOMPLETED
初始化完成量的鏈表
2.等待完成量(以下代碼有刪減)
1rt_err_t rt_completion_wait(struct rt_completion *completion,
2 rt_int32_t timeout)
3{
4 result = RT_EOK;
5 thread = rt_thread_self();
6
7 level = rt_hw_interrupt_disable();
8 if (completion-》flag != RT_COMPLETED)
9 {
10 if (timeout == 0)
11 {
12
13 }
14 else
15 {
16 /* reset thread error number */
17 thread-》error = RT_EOK;
18
19 /* suspend thread */
20 rt_thread_suspend(thread);
21 /* add to suspended list */
22 rt_list_insert_before(&(completion-》suspended_list),
23 &(thread-》tlist));
24
25 /* current context checking */
26 RT_DEBUG_NOT_IN_INTERRUPT;
27
28 /* start timer */
29 if (timeout 》 0)
30 {
31 /* reset the timeout of thread timer and start it */
32 rt_timer_control(&(thread-》thread_timer),
33 RT_TIMER_CTRL_SET_TIME,
34 &timeout);
35 rt_timer_start(&(thread-》thread_timer));
36 }
37 /* enable interrupt */
38 rt_hw_interrupt_enable(level);
39
40 /* do schedule */
41 rt_schedule();
42
43 /* thread is waked up */
44 result = thread-》error;
45
46 level = rt_hw_interrupt_disable();
47 }
48 }
49 /* clean completed flag */
50 completion-》flag = RT_UNCOMPLETED;
51
52 return result;
53}
主要做了以下工作:
關中斷:rt_hw_interrupt_disable();
掛起當前線程:rt_thread_suspend(thread);
把掛起狀態插入到線程的鏈表中:rt_list_insert_before
確保當前函數執行不是在中斷中:RT_DEBUG_NOT_IN_INTERRUPT;
設置并啟動定時器:rt_timer_start(&(thread-》thread_timer));
開中斷:rt_hw_interrupt_enable(level);
開調度器:rt_schedule();
獲取當前線程狀態:result = thread-》error;
設置完成量的標志位:completion-》flag = RT_UNCOMPLETED;
返回線程狀態
這樣就完成了線程的掛起。
3.完成完成量(以下代碼有刪減)
1 void rt_completion_done(struct rt_completion *completion)
2 {
3 level = rt_hw_interrupt_disable();
4 completion-》flag = RT_COMPLETED;
5
6 if (!rt_list_isempty(&(completion-》suspended_list)))
7 {
8 /* there is one thread in suspended list */
9 struct rt_thread *thread;
10
11 /* get thread entry */
12 thread = rt_list_entry(completion-》suspended_list.next,
13 struct rt_thread,
14 tlist);
15
16 /* resume it */
17 rt_thread_resume(thread);
18 rt_hw_interrupt_enable(level);
19
20 /* perform a schedule */
21 rt_schedule();
22 }
23 }
主要做了以下工作:
關中斷:rt_hw_interrupt_disable();
設置 flag 為 RT_COMPLETED
檢查鏈表不為空:rt_list_isempty
獲取到當前等待完成量的句柄:rt_list_entry
啟動被掛起的線程:rt_thread_resume(thread);
開中斷:rt_hw_interrupt_enable(level);
開調度:rt_schedule();
4. completion 與信號量的對比
completion API 個數少,資源占用少,只能釋放獲取,不支持多次釋放
semaphore API 個數多,資源占用較多,使用靈活,可以嘗試獲取,可以多次釋放,
5. completion 如何加入工程
標準版 RT-Thread 中的 completion 源碼在 “ t-threadcomponentsdriverssrccompletion.c”在你要使用的文件中#include completion.h直接就可以使用。
Nano 版 RT-Thread 直接拷貝completion.c 和 completion.h 添加到工程就可以使用
編輯:lyn
-
代碼
+關注
關注
30文章
4803瀏覽量
68752 -
信號量
+關注
關注
0文章
53瀏覽量
8357
原文標題:RT-Thread隱藏的寶藏之completion
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯網操作系統】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論