SylixOS 線程取消處理流程
取消一個線程要確保該線程能夠釋放其所持有的鎖、分配的內存,使整個系統保持一致性。線程取消的途徑有兩種:異步取消和延時取消。
異步取消:被取消線程收到取消信號後,立即死亡。該線程縮持有的資源可能得不到釋放,這是一種非安全的線程取消方式。
延時取消:系統默認取消方式,是一種比較安全的線程取消機制,被取消線程取消時,只是設置取消點(ptcbDel->TCB_bCancelRequest)為true,被取消線程繼續運行,等到安全位置後進行取消操作。
取消點: 在使用延遲取消機制時,一個線程在可以被取消的地方定義取消點,當收到取消請求時,被取消的線程執行到取消點時退出,或者在一個取消點調用被阻塞時退出。
關鍵結構體
程序清單2.1 TCB結構體部分節選
typedef struct __lw_tcb {
...
??? LW_LIST_LINE????????? TCB_lineManage;????????? /? 內核管理用線表????????????? /
??? LW_LIST_RING????????? TCB_ringReady;?????????? /? 相同優先級就緒環??????????? /
???
??? LW_CLASS_WAKEUP_NODE? TCB_wunDelay;????? /? 等待節點??????????????????? /
#define TCB_ulDelay?????? TCB_wunDelay.WUN_ulCounter
...
#if (LW_CFG_EVENT_EN > 0) && (LW_CFG_MAX_EVENTS > 0)
??? LW_LIST_RING????????? TCB_ringEvent;????????? ???/? 事件等待隊列表????????????? /
??? PLW_CLASS_EVENT?????? TCB_peventPtr;??????????? /? 等待事件指針????????????? ?/
??? PLW_LIST_RING??????? TCB_ppringPriorityQueue;????? /? 在 PRIORITY 隊列位置???? */
??????????????????????????????????????????????? /? 由於刪除線程時需要解等待鏈,/
?????????????????????????????????????????????? /? 這時需要確定隊列位置??????? /
#endif
#if LW_CFG_COROUTINE_EN > 0
??? LW_CLASS_COROUTINE??? TCB_crcbOrigent;???????? /? 協程起源點????????????????? /
??? PLW_LIST_RING???????? TCB_pringCoroutineHeader;?? /? 協程首地址???????????????? /
#endif??????????????????????????????????????????? /? LW_CFG_COROUTINE_EN > 0???? /
...
??? volatile ULONG??????? TCB_ulCPUId;?????????? /? 如果正在運行, 表示運行 CPU? /
??? volatile BOOL???????? TCB_bIsCand;?????????? /? 是否在候選運行表中???????? ?/
#if LW_CFG_SMP_EN > 0
??? struct __lw_tcb????? TCB_ptcbWaitStatus;????????? /? 等待狀態修改的目標線程????? */
??? PLW_LIST_LINE???????? TCB_plineStatusReqHeader;???? /? 等待修改本線程狀態?????? /
??? LW_LIST_LINE????????? TCB_lineStatusPend;????????? /? 等待目標線程狀態修改?? ????/
#endif?????????????????????????????????????????????? /? LW_CFG_SMP_EN????????????? /
...
??? PLW_EVENTSETNODE????? TCB_pesnPtr;????? /? 指向該線程等待????????????? /
...
#if LW_CFG_THREAD_CANCEL_EN > 0
??? BOOL????????????????? TCB_bCancelRequest;???? /? 取消請求??????????????????? /
??? INT?????????????????? TCB_iCancelState;???????? /? 取消狀態??????????????????? /
??? INT?????????????????? TCB_iCancelType;????????? /? 取消類型??????????????????? /
#endif???????????????????????????????????????? /? LW_CFG_THREAD_CANCEL_EN???? /
...
#if LW_CFG_THREAD_DEL_EN > 0
??? struct __lw_tcb????? TCB_ptcbDeleteMe;?????? /? 要將本線程刪除的 TCB??????? */
??? struct __lw_tcb????? TCB_ptcbDeleteWait;???????? /? 等待對方刪除的 TCB????????? */
#endif???????????????????????????? ????????????????/? LW_CFG_THREAD_DEL_EN > 0??? /
??? UINT8???????????????? TCB_ucStackAutoAllocFlag;???? /? 堆棧是否有系統在堆中開辟?? /????????
??? PVOID???????????????? TCB_pvVProcessContext;?????? /? 進程上下文???????????????? /
...
} LW_CLASS_TCB;
程序清單2.2 等待隊列
typedef union {
??? PLW_LIST_RING???????? WL_pringFifo;????????????????? /? 基於先入先出的等待隊列?? /
??? PLW_LIST_RING???????? WL_pringPrio[__EVENT_Q_SIZE];? /? 基於優先級的等待隊列?? /
} LW_UNION_WAITLIST;
typedef LW_UNION_WAITLIST *PLW_UNION_WAITLIST;
typedef struct {
??? LW_UNION_WAITLIST???? WQ_wlQ;??????????????? /? 等待隊列??????????????????? /
??? UIN×××6??????????????? WQ_usNum;??????????????? /? 等待隊列中的線程個數??????? /
} LW_CLASS_WAITQUEUE;
typedef LW_CLASS_WAITQUEUE *PLW_CLASS_WAITQUEUE;
程序清單2.3 事件集
typedef struct {???????????????????????????????????????????? /? 事件集??????????????????? /
??? LW_LIST_MONO???????? EVENTSET_monoResrcList;???? /? 空閑資源表?????????????? /
??? UINT8??????????????? EVENTSET_ucType;????????????? /? 類型????????????????????? /
??? PLW_LIST_LINE??????? EVENTSET_plineWaitList;??????? /? 指向第一個等待線程??????? /
??? ULONG??????????????? EVENTSET_ulEventSets;???????? /? 32 bit 事件位???????????? /
??? ULONG??????????????? EVENTSET_ulOption;?????????? /? 事件集選項??????????????? /
??? UIN×××6?????????????? EVENTSET_usIndex;???????????? /? 數組中的索引????????????? /
??? CHAR???????????????? EVENTSET_cEventSetName[LW_CFG_OBJECT_NAME_SIZE];
???????????????????????????????????????????????????????? /? 事件標誌組名????????????? ?/
} LW_CLASS_EVENTSET;
typedef LW_CLASS_EVENTSET *PLW_CLASS_EVENTSET;
typedef struct {????????????????????????????????????????????? /? 事件集節點?????????????? /
??? LW_LIST_LINE???????? EVENTSETNODE_lineManage;???? /? 事件標誌組管理表??????? /
???
??? PVOID???????? ???????EVENTSETNODE_ptcbMe;?????? /? 指向等待任務的TCB??????? /
??? PVOID??????????????? EVENTSETNODE_pesEventSet;?? /? 指向標誌組??????????????? /
??? ULONG??????????????? EVENTSETNODE_ulEventSets;?? /? 標誌組開始等待?????????? /
??? UINT8??????????????? EVENTSETNODE_ucWaitType;???? /? 等待類型???????????????? /
} LW_CLASS_EVENTSETNODE;
typedef LW_CLASS_EVENTSETNODE?? *PLW_CLASS_EVENTSETNODE;
typedef PLW_CLASS_EVENTSETNODE?? PLW_EVENTSETNODE;
流程
API_ThreadCancel函數流程:
? ? ? 圖3.1 API_ThreadCancel函數
API_ThreadTestCancel函數流程:
圖3.2 API_ThreadTestCancel函數
pthread_delete函數流程:
圖3.3 pthread_delete函數
__threadDelete函數流程:
圖3.4 __threadDelete函數
SylixOS 線程取消處理流程