Windows核心编程 --- 线程相关

1,在调用了RunTime的C/C++程序中调用_beginthreadex而不是CreateThread来创建线程

2,CreateThread创建的线程栈的地址空间大小由cbStackSize和/STACK链接器开关中取其中较大的那一个。

3,ExitThread会销毁线程的堆栈,并且DLL能收到DLL_THREAD_DETACH通知,而TerminateThread不会销毁线程的堆栈,并且DLL不能收到通知。

4,创建线程时候首先将EIP修改为RtlUserThreadStart,ESP,EBP修改为堆栈指针,然后 CALL ThreadProc,最后线程返回了调用ExitThread

5,GetCurrentProcess和GetCurrentThread不会再进程的句柄表中新建句柄,而是一个伪句柄。0xFFFFFFFF表示当前进程,而0xFFFFFFFE表示当前线程。

6,将当前进程,线程句柄的伪句柄转换为真正的句柄:利用DuplicateHandle:

HANDLE hProcess;

DuplicateHandle(

    GetCurrentProcess(),

    GetCurrentProcess(),

    GetCurrentProcess(),

    &hProcess,

    0,

    FALSE,

    DUPLICATE_SAME_ACCESS

);

7,挂起线程只有用CreateToolhelp32Snapshot创建一个本进程的线程快照,然后依次把每个线程SusPend,或者用调试器处理WaitForDebugEvent返回的调试事件时候,Windows会冻结所有线程,直到调试器调用ContinueDebugEvent。

8,睡眠Sleep(0)表示这个线程放弃时间片的剩余部分,让系统强制调度其他线程。

9,SwitchToThread与Sleep类似,但是SwitchToThread会检查当前是否有饥饿线程,如果饥饿线程,即使优先级比主调线程低还是会让饥饿线程运行一段事件,而Sleep(0)就是直接重新调度,这就可能使低优先级的饥饿线程还是不能执行。

10,在获取CONTEXT前先要初始化CONTEXT的dwSize为sizeof(CONTEXT),然后在SetThreadContext前要再次初始化CONTEXT的ContextFlags成员。

11,线程优先级:0(低)~31(高),windows是抢占式多任务操作系统,所以低优先级可以被高优先级线程所抢占和打断,在操作系统中唯一一个0优先级的线程是页面清零线程,负责在没有进程执行时候将内置内存页面清零。

12,一个进程中的线程优先级和进程优先级和线程优先级相关,设置优先级可以用SetPriorityClass,获取优先级可以用GetPriorityClass获取。

13,系统会动态提升线程优先级,也就是说饥饿线程发生的清空,系统会提升1~15的优先级线程,可以用SetProcessPriorityBoost和SetThreadPriorityBoost来禁止优先级的动态提升。






猜你喜欢

转载自blog.csdn.net/a893574301/article/details/80709267
今日推荐