基本概念
程序是指令的有序集合,其本身沒有任何運行的含義,是一個靜態的概念。而進程是程序在處理機上的一次執行過程,它是一個動態的概念。進程是由程序、數據和進程控制塊三部分組成的。
進程是操作系統資源分配的基本單位,而線程是任務調度和執行的基本單位。
每個進程都有獨立的代碼和數據空間(程序上下文),程序之間的切換會有較大的開銷;線程可以看做輕量級的進程,同一類線程共享代碼和數據空間,每個線程都有自己獨立的運行棧和程序計數器(PC),線程之間切換的開銷小。
系統在運行的時候會爲每個進程分配不同的內存空間;而對線程而言,除了CPU外,系統不會爲線程分配內存(線程所使用的資源來自其所屬進程的資源),線程組之間只能共享資源。
在rtos threadx中,只有一個程序,運行時可以看做只有一個進程,這個進程下包含多個線程。
線程控制塊
線程控制塊(TCB)用來保持運行時線程狀態的數據結構,在線程切換時用來保持線程信息。
typedef struct TX_THREAD_STRUCT
{
/* The first section of the control block contains critical
information that is referenced by the port-specific
assembly language code. Any changes in this section could
necessitate changes in the assembly language. */
ULONG tx_thread_id; /* Control block ID */
ULONG tx_run_count; /* Thread's run counter */
VOID_PTR tx_stack_ptr; /* Thread's stack pointer */
VOID_PTR tx_stack_start; /* Stack starting address */
VOID_PTR tx_stack_end; /* Stack ending address */
ULONG tx_stack_size; /* Stack size */
ULONG tx_time_slice; /* Current time-slice */
ULONG tx_new_time_slice; /* New time-slice */
/* Define pointers to the next and previous ready threads. */
struct TX_THREAD_STRUCT
*tx_ready_next,
*tx_ready_previous;
/* Define the port extension field. This typically is defined
to white space, but some ports of ThreadX may need to have
additional fields in the thread control block. This is
defined in the file tx_port.h. */
TX_THREAD_PORT_EXTENSION
/***************************************************************/
/* Nothing after this point is referenced by the target-specific
assembly language. Hence, information after this point can
be added to the control block providing the complete system
is recompiled. */
CHAR_PTR tx_thread_name; /* Pointer to thread's name */
UINT tx_priority; /* Priority of thread (0-31)*/
UINT tx_state; /* Thread's execution state */
UINT tx_delayed_suspend; /* Delayed suspend flag */
UINT tx_suspending; /* Thread suspending flag */
UINT tx_preempt_threshold; /* Preemption threshold */
ULONG tx_priority_bit; /* Priority ID bit */
/* Define the thread's entry point and input parameter. */
VOID (*tx_thread_entry)(ULONG);
ULONG tx_entry_parameter;
/* Define the thread's timer block. This is used for thread
sleep and timeout requests. */
TX_INTERNAL_TIMER
tx_thread_timer;
/* Define the thread's cleanup function and associated data. This
is used to cleanup various data structures when a thread
suspension is lifted or terminated either by the user or
a timeout. */
VOID (*tx_suspend_cleanup)(struct TX_THREAD_STRUCT *);
VOID_PTR tx_suspend_control_block;
struct TX_THREAD_STRUCT
*tx_suspended_next,
*tx_suspended_previous;
ULONG tx_suspend_info;
VOID_PTR tx_additional_suspend_info;
UINT tx_suspend_option;
UINT tx_suspend_status;
/* Define a pointer for Green Hills use. */
VOID_PTR tx_eh_globals;
/* Define pointers to the next and previous threads in the
created list. */
struct TX_THREAD_STRUCT
*tx_created_next,
*tx_created_previous;
} TX_THREAD;
域 | 意義 |
---|---|
tx_thread_id | 線程控制塊id |
tx_run_count | 線程運行計數器 |
tx_stack_ptr | 線程堆棧指針 |
tx_stack_start | 堆棧起始地址 |
tx_stack_end | 堆棧結束地址 |
tx_stack_size | 堆棧大小 |
tx_time_slice | 當前時間片(剩餘運行時間) |
tx_new_time_slice | 新的時間片 |
tx_ready_next | 指向下一個就緒線程指針 |
tx_ready_previous | 指向前一個就緒線程指針 |
tx_thread_name | 線程名字指針 |
tx_priority | 線程優先級 (0-31,0爲最高優先級,31最低優先級) |
tx_state | 線程當前狀態 |
tx_delayed_suspend | 線程延遲掛起標誌 |
tx_suspending | 線程掛起過程標誌,正在掛起 |
tx_preempt_threshold | 搶佔門限 |
tx_thread_entry | 入口函數指針 |
tx_entry_parameter | 入口函數參數 |
tx_thread_timer | 線程定時器,用於線程sleep |
tx_suspend_cleanup | 線程清理函數 |
tx_suspended_next | 指向下一個掛起線程指針 |
tx_suspended_previous | 指向前一個掛起線程指針 |
tx_created_next | 線程created list中,指向下一個線程指針 |
tx_created_previous | 線程created list中,指向前一個線程指針 |
線程狀態
線程包括5中狀態:就緒態,掛起態,執行態,中止態,完成態。
線程堆棧
線程堆棧用於存儲局部變量,函數調用上下文,線程切換上下文等。 堆棧大小和堆棧使用的內存由開發者決定,分配。
線程管理鏈表
線程創建時,TCB會插入到一個雙向鏈表中。_tx_thread_created_ptr指向雙向鏈表頭部
就緒隊列
線程就緒隊列由數組和雙向鏈表組成。
#define TX_MAX_PRIORITIES 32
TX_THREAD * _tx_thread_priority_list[TX_MAX_PRIORITIES];
數組元素有32個,數組元素爲指向TCB的指針,每一個tcb指針組成雙向鏈表,tx_ready_next和tx_ready_previous分別指向下一個tcb和前一個tcb。
每個數組元素索引爲線程優先級,同一個優先級的所有線程都在同一個數組鏈表中。
就緒優先級位圖
就緒優先級位圖_tx_thread_priority_map由32位bit表示,某位爲1表示對應就緒優先級數組中指針不爲NULL,鏈表中有就緒線程。
bit0對應_tx_thread_priority_list[0],
bit1對應_tx_thread_priority_list[1],
。。。
bit31對應_tx_thread_priority_list[31]
ULONG _tx_thread_priority_map;
搶佔位圖
_tx_thread_preempted_map表示線程搶佔是按照tx_preempt_threshold值進行判斷搶佔的。某bit爲1表示,對應優先級線程被搶佔,原因是搶佔線程的優先級大於被搶佔線程的tx_preempt_threshold值。
例如,線程a,tx_priority優先級爲14,tx_preempt_threshold門限值爲10。
線程b,tx_priority優先級爲12,由於12大於線程a的tx_preempt_threshold門限值爲10,所以無法搶佔線程a。
線程c,tx_priority優先級爲9,由於9小於線程a的tx_preempt_threshold門限值爲10,所以可以搶佔線程a。
並且標記_tx_thread_preempted_map的bit14爲1.
注:tx_priority值越小,優先級越大