线程由2部分构成:线程的内核对象和线程堆栈。操作系统使用内核对象对线程进行管理,堆栈则用于维护线程在执行代码时需要的所有函数参数和局部变量。一个进程中的多个线程之间共享这个进程的代码段、地址空间、内核对象句柄等。
可以使用createthread、__beginthread函数来创建一个线程。但是一般建议使用beginthread,虽然它也是调用的createthread函数来创建线程的。但是beginthread会另外初始化C运行时库,保证C库的线程安全。比如errno一般是全局共享的,如果使用createthread则所有线程都共享这一个errno,但是如果使用beginthread则每个线程都有自己的errno不会互相影响。
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
uintptr_t _beginthread(
_beginthread_proc_type _StartAddress,
unsigned _StackSize,
void* _ArgList
);
uintptr_t _beginthreadex(
void* _Security,
unsigned _StackSize,
_beginthreadex_proc_type _StartAddress,
void* _ArgList,
unsigned _InitFlag,
unsigned* _ThrdAddr
);
暂停和重启线程
DWORD SuspendThread(HANDLE hThread);
DWORD ResumeThread(HANDLE hThread);
睡眠
VOID Sleep(DWORD dwMilliSeconds);
转换到另一线程
// 转换到另一线程运行
BOOL SwithToThread();
线程的运行时间
单纯的使用GetTimeTick获取时间差并不可靠,因为线程可能被中断,可能被挂起,也可能退出。为了获得线程具体的运行时间,可以通过getthreadtimes:
BOOL GetThreadTimes(
HANDLE hThread,
PFILETIME pftCreationTime,// 线程创建时间
PFILETIME pftExitTime,// 线程退出时间,如果正在运行则未定义
PFILETIME pftKernelTime,// 线程内核态运行时间
PFILETIME pftUserTime // 线程用户态运行时间
);
BOOL GetProcessTimes(
HANDLE hThread,
PFILETIME pftCreationTime,
PFILETIME pftExitTime,//
PFILETIME pftKernelTime,//
PFILETIME pftUserTime //
);
// 频率*计数就是运行时间
BOOL QueryPerformanceFrequency(LARG_INTERGER *pliFrequence);
BOOL QueryPerformanceCounter(LARG_INTERGER *pliCounter);
BOOL GetThreadContext(
HANDLE hThread,
PCONTEXT pContext;
);
线程优先级从0(最低)~31(最高),系统调度的时候总是先调度优先级高的线程,除非优先级高的线程不存在则调度优先级低的线程。Windows支持6个应用程序优先级:
优先级 | 描述 |
---|---|
实时 | 进场中的线程必须立即对事件做出相应,以便执行关键事件的任务。该进场中的线程还会抢先于操作系统组件之前运行,使用本优先级时必须极端小心 |
高 | 进场中的线程必须立即对时间做出相应,task manager(任务管理器)在这个级别上运行,以便用户可以撤销脱离控制的程序 |
高于正常 | 进场中的线程在正常优先级与高优先级之间运行 |
正常 | 正常,没有特殊的调度需求 |
低于正常 | |
空闲 | 进场中的线程在系统空闲时运行。该进程通常由屏幕保护程序或者后台实用程序和搜集统计数据的软件使用 |
应该尽可能避免使用实时优先级类。实际上Windows NT 3.1的早期测试版并没有向应用程序展示这个优先级类,尽管该操作系统支持这个类。实时优先级是很高的优先级它可能干扰操作系统任务的运行,因为大多数操作系统线程均以较低的优先级来运行。
BOOL SetPriorityClass(HANDLE hProcess,DWORD fdwPriority);
DWORD GetPriorityClass(HANDLE hProcess);
// 进程优先级类标识符
//实时:REALTIME_PRIORITY_CLASS
//高:HIGH_PRIORITY_CLASS
//高于正常:ABOVE_NORMAL_PRIORITY_CLASS
//正常:NORMAL_PRIORITY_CLASS
//低于正常:BELOW_NORMAL_PRIORITY_CLASS
//空闲:IDLE_PRIORITY_CLASS
BOOL SetThreadPriority(HANDLE hThread,DWORD fdwPriority);
DWORD GetThreadPriority(HANDLE hThread);
// 进程优先级类标识符
//实时:THREAD_PRIORITY_TIME_CRITICAL
//最高:THREAD_PRIORITY_HIGHEST
//高于正常:THREAD_PRIORITY_ABOVE_NORMAL
//正常:THREAD_PRIORITY_NORMAL
//低于正常:THREAD_PRIORITY_BELOW_NORMAL
//空闲:THREAD_PRIORITY_IDLE