界區( Critical Section),每次只准許一個線程進入臨界區,進入后不允許其他線程進入。多線程程序的開發方式不同於裸機程序,多個線程在宏觀上是並發運行的,因此使用一個共享資源是需要注意,否則就可能出現錯誤的運行結果。
#include <rtthread.h> #include <stm32f10x.h> #include "test.h" rt_uint32_t g_tmp;/* 定義一個全局變量*/ /* 變量分配4字節對齊 */ ALIGN(RT_ALIGN_SIZE) /* 靜態線程的 線程堆棧*/ static rt_uint8_t thread1_stack[512]; static rt_uint8_t thread2_stack[512]; /* 靜態線程的 線程控制塊 */ static struct rt_thread thread_test1; static struct rt_thread thread_test2; static void test1_thread_entry(void* parameter); static void test2_thread_entry(void* parameter); void demo_thread_creat(void) { rt_err_t result; /* 創建靜態線程 : 優先級 15 ,時間片 2個系統滴答 */ result = rt_thread_init(&thread_test1, "test1", test1_thread_entry, RT_NULL, (rt_uint8_t*)&thread1_stack[0], sizeof(thread1_stack), 16, 2); if (result == RT_EOK) { rt_thread_startup(&thread_test1); } /* 創建靜態線程 : 優先級 16 ,時間片 1個系統滴答 */ result = rt_thread_init(&thread_test2, "test2", test2_thread_entry, RT_NULL, (rt_uint8_t*)&thread2_stack[0], sizeof(thread2_stack), 15, 1); if (result == RT_EOK) { rt_thread_startup(&thread_test2); } } void test1_thread_entry(void* parameter) { rt_uint32_t i; g_tmp = 0; rt_kprintf("g_tmp=:%d \r\n", g_tmp); for(i=0; i<10000; i++) { g_tmp++; } rt_kprintf("g_tmp=:%d \r\n", g_tmp); } void test2_thread_entry(void* parameter) { rt_thread_delay(100);// 1 rt_thread_delay(100);兩種情況下得到兩張圖片
g_tmp++;
}

結果分析:
在 test1 線程的 for 循環中我們對 i 做了 10000 次累加,如果沒有其他線程的“干預”,那么全局變量 g_tmp 的值應該是 10000,現在的輸出結果是 10001,這意味全局變量 g_tmp 的值被線程 2 修改過。整個程序運行過程中各個線程的狀態變化是這樣的: rt_application_init 中創建兩個線程之后,由於 test2 線程的優先級比 test1 線程的優先級高,因此 test2 線程先運行,其線程處理函數第一句為 rt_thread_delay(1), 這會使得 test2 線程被掛起,掛起時間為 1 個時間片,在 test2 線程掛起的這段時間中, test1 線程是所有就緒態線程中優先級最高的線程,因此被內核調度運行。 在 test1 線程執行了一部分代碼后, 1 個 tick 時間到, test2 線程被喚醒,從而成為所有就緒線程中優先級最高的線程,因此會被立刻調度運行, test1 線程被 test2 線程搶占, test2 線程中對全局變量 g_tmp 做累加操作,接下來 test2 線程執行完畢, test1 線程再次被調度運行,根據程序的運行結果可以看出,此時 test1 線程繼續執行,但是我們並不知道此時 test1 線程大致是從什么地方在開始執行的,從最后的輸出結果來看,只能得知此時test1 線程還沒有執行到第二條 rt_kprintf 輸出語句。最后 test1 線程再次打印全局變量 g_tmp的值,其值就應該是 10001。當 test2線程中的第一句為 rt_thread_delay(100)的時候,在 test2線程休眠的整個時間里,test1 線程都已經執行完畢,因此最后的輸出結果為 10000。
從以上可以看到: 當公共資源在多個線程中公用時,如果缺乏必要的保護錯誤,最后的輸出結果可能與預期的結果完全不同。為了解決這種問題,需要引入線程間通信機制,這就
是所謂的 IPC 機制( Inter-Process Communication)。
