对于如何用VS的C++处理Windows上的线程,ChatGPT向我提供了代码模板,被我记了下来:
How to set the timeslices between different threads in Windows 10 by C++?
然而事情不能就这么算了,里面的不少函数我还是不明白,在这里参考微软开发文档,做个记录:
1.函数CreateThread
CreateThread function (processthreadsapi.h)
此函数用于创建一个在另一个进程的虚拟存储空间之内运行的进程。语法规则:
HANDLE CreateThread(
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] SIZE_T dwStackSize,
[in] LPTHREAD_START_ROUTINE lpStartAddress,
[in, optional] __drv_aliasesMem LPVOID lpParameter,
[in] DWORD dwCreationFlags,
[out, optional] LPDWORD lpThreadId
);
参数:
(1)[in, optional] lpThreadAttributes
这是一个指向SECURITY_ATTRIBUTES结构体的指针,用于确定是否所返回的句柄可以被子进程所继承。如果此参数为NULL,则句柄不可被继承。SECURITY_ATTRIBUTES结构体中的lpSecurityDescriptor成员为新线程指定了一个安全描述符。如果lpThreadAttributes为NULL,则线程获得默认的安全描述符。
(2)[in] dwStackSize
堆栈的初始大小,以字节为单位。系统将此值舍入到最近的页面。如果这个参数是0,新线程使用默认的执行大小。
(3)[in] lpStartAddress
指向线程函数的指针。代表了线程的起始地址。
(4)[in, optional] lpParameter
指向线程函数参数的指针。
(5) [in] dwCreationFlags
控制线程创建的标志,具体的值如下:
(6)[out, optional] lpThreadId
指向接收线程标识符的变量的指针。如果此参数为NULL,线程标识符是不会返回的。
返回值:
如果函数成功了,就会返回新线程的句柄。
2.函数WaitForSingleObject
WaitForSingleObject function(synchapi.h)
等待指定对象处于信号状态或超时间隔结束。语法规则:
DWORD WaitForSingleObject(
[in] HANDLE hHandle,
[in] DWORD dwMilliseconds
);
参数:
(1) [in] hHandle
这是对象的句柄,如果这个句柄在等待仍然挂起时被关闭,则该函数的行为未定义。这个句柄必须有SYNCHRONIZE访问权限。
(2)[in] dwMilliseconds
超时时间间隔,单位为毫秒。如果指定了非零值,则该函数将等待,直到对象发出信号或间隔时间过去。当为0时,则如果对象没有信号,该函数不会进入等待状态;它总是立即返回。当为INFINITE时,则该函数只会在对象收到信号时返回。对于Windows10而言,dwMilliseconds值不包括在低功耗状态下花费的时间。例如,当计算机处于睡眠状态时,超时不会继续计数。
返回值:
如果函数成功了,返回值指明导致函数返回的事件,结果可能是下面之一:
备注:
WaitForSingleObject函数检查指定对象的当前状态。如果对象的状态为非信号状态,则调用线程进入等待状态,直到对象被信号或超时间隔结束。该函数可用于等待如下对象:
Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer
如果你有一个创建多个窗口的线程,就不要用这个函数。
3.函数GetCurrentThread:
GetCurrentThread function (processthreadsapi.h)
检索调用线程的pseudo handle。参数为void,返回值为当前线程的pseudo handle。
备注:
pseudo handle是一个特殊的常量,它被解释成当前线程的句柄,每当需要线程句柄时,调用的线程可以使用句柄表示自己。Pseudo handles不能被子进程所继承。当pseudo handle不再被需要时不需要关闭它。对这种句柄调用CloseHandle函数没有影响。如果pseudo handle被DuplicateHandle函数所复制,复制出的句柄必须被关闭。
4.函数GetProcessAffinityMask:
GetProcessAffinityMask function (winbase.h)
检索指定进程的进程关联掩码和系统的系统关联掩码。语法规则:
BOOL GetProcessAffinityMask(
[in] HANDLE hProcess,
[out] PDWORD_PTR lpProcessAffinityMask,
[out] PDWORD_PTR lpSystemAffinityMask
);
参数:
(1)[in] hProcess
需要关联的掩码的进程的句柄。此句柄必须有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION访问权限。
(2)[out] lpProcessAffinityMask
指向变量的指针,接收指定线程的关联掩码。
(3)[out] lpSystemAffinityMask
指向变量的指针,接收系统的关联掩码。
返回值:
如果函数成功,返回值是非零的,并且函数将lpProcessAffinityMask和lpSystemAffinityMask指向的变量设置为适当的关联掩码。
(我这的“关联掩码”英文是affinity mask)
5.函数SetThreadAffinityMask
SetThreadAffinityMask function (winbase.h)
为特定的线程设置processor关联掩码
语法规则:
DWORD_PTR SetThreadAffinityMask(
[in] HANDLE hThread,
[in] DWORD_PTR dwThreadAffinityMask
);
参数:
1.[in] hThread
将要设置affinity mask的线程的句柄。
2.[in] dwThreadAffinityMask
线程的affinity mask
返回值:
如果函数成功了,返回值是线程以往的affinity mask。如果函数失败,就返回0。
6.函数timeBeginPeriod
timeBeginPeriod function (timeapi.h)
该函数请求周期计时器的最小分辨率。
语法规范:
MMRESULT timeBeginPeriod(
UINT uPeriod
);
参数:
uPeriod
应用程序或设备驱动程序的最小计时器分辨率(以毫秒为单位)。更小的值指出了更高(更准确)的分辨率。
返回值:
如果成功了就返回了TIMERR_NOERROR。如果uPeriod所指的分辨率超出了范围,就返回TIMERR_NOCANDO。
备注:
在使用计时器服务之前立即调用此函数,并在完成使用计时器服务后立即调用timeEndPeriod函数。您必须将每次对timeBeginPeriod的调用与对timeEndPeriod的调用相匹配,并在两次调用中指定相同的最小分辨率。一个应用程序可以多次调用timeBeginPeriod,只要每次调用都与对timeEndPeriod的调用相匹配。