PoEdu - Windows階段班 【Po學校】Lesson006_線程_線程的啟動到消亡 &線程狀態 & 安全執行緒 & CONTEXT結構體 & 令牌鎖

來源:互聯網
上載者:User

標籤:mon   調用   demo   包含   struct   處理機   ges   not   設計者   

    • 011_線程啟動到死亡的詳細講解
      • 1. 線程核心對象
        • 使用計數 2 ##決定當前線程何時銷毀
        • 暫停計數 1 ##UINT類型初始為1,可以暫停多次,如置為0則取消暫停。
        • 結束代碼 STILL_ACTIVE
        • Signaled FALSE
        • CONTEXT 為空白
      • 2. 棧
        ##在隸屬於當前進程的空間中,分配一塊“棧”空間,以供線程使用
        • 參數 lpParam
        • 入口地址 lpfnAddr
      • 3. CONTEXT
        ##線程上一次運行時的寄存器
        • IP(指令寄存器) void RtlUserThreadStart(未公開的函數)(lpParam,lpFnAddr)
        • SP(棧寄存器) lpFnAddr
      • 4. 交給CPU調度
      • 5. RtlUserThreadStart
        • SEH ##設定結構化異常
        • 調用線程函數,傳遞lpParam
        • 等待線程函數的返回
        • ExitThread ## 使用計數遞減
    • 012_beginthreadex和CreateThread
      • 多線程運行庫的設定
      • _beginthreadex() 函數隸屬於C標準的運行庫,要包含標頭檔: process.h
      • 非安全執行緒:
        • 多線程訪問全域變數時,會有出錯的機率。
        • 舉例C語言的錯誤處理機制:errno 非安全執行緒
        • C語言的設計者,為瞭解決線程的安全問題,給出了_beginthreadex()函數。
      • _beginthreadex()函數的區別:
        • 1 參數與 CreateThread()函數的參數意義相同,但其類型已經不同。
        • 2 beginthreadex()比CreateThread()函數,多開闢了一段空間,分配在堆上面,儲存一些全域的變數。以期安全執行緒。多分配了堆空間後,才來調用CreateThread();
        • 3 使用beginthreadex()要配套_endthreadex()使用.
      • 建議使用_beginthreadex(),有多分配一段堆空間。
        • _beginthread()函數不建議使用,因為其並沒有多分配一段堆空間。這裡要注意使用EX版本的函數。
    • 013_線程狀態
    • 014_線程的掛起轉態
      • 啟動
        • CONTEXT 初始
        • 使用計數 置為2
        • 暫停計數 置為1
          • 在後續CreateThread完成後,減1得出0,為0則進入CPU的調度。當前線程是可執行檔狀態。
      • 運行
        • 執行我們的函數
          • 時不時的切換線程,將CPU寄存器的狀態寫入CONTEXT
          • 切換到當前時,先讀取CONTEXT
      • 掛起
        • SuspendThread() 32位 Wow64SuspendThread() 64位
          • 調用暫停線程函數SuspendThread(),函數會把暫停計數+1
          • SuspendThread函數會返回0,第一次調用結束時返回1;第二次調用時返回1,第二次結束時返回2. 此函數有調用時的返回,與結束時的返回。
        • ResumeThread() 恢複掛起線程
          • 調用此函數,會把當前線程的暫停計數-1
          • 有幾次掛起,就要有幾次恢複調用,不然線程仍然不會進入運行。
        • 不建議使用線程的掛起:
          • 如果線程入口函數裡面,有new新的堆空間,而作業系統切換線程時,有可能會使得這塊堆空間,在被佔用的情況下,卻沒有佔用的標記。此時當此堆空間被訪問時,就出了非常隱形BUG。
          • 要區分2種掛起:
          • 1 作業系統切換線程時的“掛起”——在“池”中
            • 準確來說是“切換”線程。按作業系統的演算法,線程在進行CPU調度時,所產生的暫停。
          • 2 SuspendThread()函數產生的掛起 ——不在“池”中
            • 掛起的線程被拿出CPU的線程運行調度池
    • 015_線程 等待、休眠、及饑餓線程
      • 等待休眠 Sleep()
        • Sleep(100); 表示休眠100毫秒後,CPU再來運行;
        • 這裡100毫秒並不能準確不差,因為windows作業系統非即時的,CPU的運行時調度也是非即時的;所以在時間方面有一點誤差,只能說是無限接近100毫秒。
        • 放棄當前的時間片,在一段時間之內,CPU不會調度此線程
        • Sleep(INFINITE) 永遠等待
          • INFINITE 其值為-1;
          • 一直等待到進程結束
        • Sleep(0) 放棄線程執行時間片
        • SwitchToThread() 把CPU剩餘的時間片,分配給"饑餓度"較高的線程.
          • 調度另外一個線程,也就是把CPU的執行循環給另外一個線程身上。
          • CPU時間片“饑餓度”:如果一此線程相對時間片很少,或者一直沒有得到執行,我們就稱其為“饑餓”線程。饑餓度相對較高。
    • 016_CONTEXT結構體
      • 源碼
        typedef struct _CONTEXT {    //    // The flags values within this flag control the contents of    // a CONTEXT record.    //    // If the context record is used as an input parameter, then    // for each portion of the context record controlled by a flag    // whose value is set, it is assumed that that portion of the    // context record contains valid context. If the context record    // is being used to modify a threads context, then only that    // portion of the threads context will be modified.    //    // If the context record is used as an IN OUT parameter to capture    // the context of a thread, then only those portions of the thread‘s    // context corresponding to set flags will be returned.    //    // The context record is never used as an OUT only parameter.    //    DWORD ContextFlags;    //    // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is    // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT    // included in CONTEXT_FULL.    //    DWORD   Dr0;    DWORD   Dr1;    DWORD   Dr2;    DWORD   Dr3;    DWORD   Dr6;    DWORD   Dr7;    //    // This section is specified/returned if the    // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.    //    FLOATING_SAVE_AREA FloatSave;    //    // This section is specified/returned if the    // ContextFlags word contians the flag CONTEXT_SEGMENTS.    //    DWORD   SegGs;    DWORD   SegFs;    DWORD   SegEs;    DWORD   SegDs;    //    // This section is specified/returned if the    // ContextFlags word contians the flag CONTEXT_INTEGER.    //    DWORD   Edi;    DWORD   Esi;    DWORD   Ebx;    DWORD   Edx;    DWORD   Ecx;    DWORD   Eax;    //    // This section is specified/returned if the    // ContextFlags word contians the flag CONTEXT_CONTROL.    //    DWORD   Ebp;    DWORD   Eip;    DWORD   SegCs;              // MUST BE SANITIZED    DWORD   EFlags;             // MUST BE SANITIZED    DWORD   Esp;    DWORD   SegSs;    //    // This section is specified/returned if the ContextFlags word    // contains the flag CONTEXT_EXTENDED_REGISTERS.    // The format and contexts are processor specific    //    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];} CONTEXT;

          


    • 017_安全執行緒及上鎖
      • 樣本
      • // ContextDemo.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#include <windows.h>#include <process.h>BOOL bUseing = FALSE;unsigned int __stdcall ThreadRun(void* lParam){int nNum = 0;while (true){if (!bUseing){bUseing = TRUE;_tprintf(TEXT("ThreadRun:%d\r\n"), nNum++);bUseing = FALSE;}}}unsigned int __stdcall ThreadMonitor(void* lParam){HANDLE hThread = (HANDLE)(lParam);while (true){CONTEXT context;context.ContextFlags = CONTEXT_ALL;SuspendThread(hThread);GetThreadContext(hThread, &context);if (!bUseing){bUseing = TRUE;_tprintf(TEXT("EAX:0x%x ESP:0x%x EIP:0x%x\r\n"), context.Eax, context.Esp, context.Eip);bUseing = FALSE;}ResumeThread(hThread);}}int main(){HANDLE hThreads[2];hThreads[0] = (HANDLE)_beginthreadex(nullptr, 0, ThreadRun,nullptr, 0, nullptr);hThreads[1] = (HANDLE)_beginthreadex(nullptr, 0, ThreadMonitor,hThreads[0], 0, nullptr);WaitForMultipleObjects(sizeof(hThreads)/sizeof(HANDLE),hThreads,true,INFINITE);for (int i = 0; i<sizeof(hThreads)/sizeof(HANDLE);++i){CloseHandle(hThreads[i]);}    return 0;}

         

PoEdu - Windows階段班 【Po學校】Lesson006_線程_線程的啟動到消亡 &線程狀態 & 安全執行緒 & CONTEXT結構體 & 令牌鎖

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.