【发布时间】:2021-09-15 17:10:01
【问题描述】:
我期望发生的事情:
由于进程亲和性仅限于单个核心,因此当前进程的所有线程都必须竞争执行时间。
由于线程 a 的优先级高于线程 b 并且它从不阻塞,因此线程 b 永远不会被执行。
我所看到的:
线程 b 被虚假执行。
为什么会这样?有没有办法用 WinAPI 强制执行这个执行逻辑?
#include <iostream>
#include <thread>
#include <windows.h>
using namespace std;
DWORD WINAPI a_function(LPVOID lpParam)
{
while (true) {
}
return 0;
}
DWORD WINAPI b_function(LPVOID lpParam)
{
while (true) {
cout << "b" << endl;
}
return 0;
}
int main()
{
DWORD affinityMask = 1u;
BOOL res = SetProcessAffinityMask(GetCurrentProcess(), affinityMask);
if (!res) {
return -1;
}
HANDLE a_handle = CreateThread(nullptr, 0, a_function, nullptr, CREATE_SUSPENDED, nullptr);
HANDLE b_handle = CreateThread(nullptr, 0, b_function, nullptr, CREATE_SUSPENDED, nullptr);
SetThreadPriority(a_handle, THREAD_PRIORITY_NORMAL);
SetThreadPriority(b_handle, THREAD_PRIORITY_BELOW_NORMAL);
ResumeThread(a_handle);
ResumeThread(b_handle);
WaitForSingleObject(a_handle, INFINITE);
return 0;
}
输出:
b
b
b
b
b
注意:我没有使用 ResumeThread() / SuspendThread() 因为:
“SuspendThread 函数不用于线程同步,因为它不控制代码中线程执行暂停的点。” (source)
【问题讨论】:
-
您的系统是否只有一个核心?
-
@fredrik 不,但我将进程关联掩码设置为使用单核。
-
由于线程 a 的优先级高于线程 b,并且它从不阻塞,因此线程 b 永远不会被执行。 不要认为这一定是真的。如何和展示你的测试
-
while (true) { }在技术上是 UB - 检查生成的代码 - 它可能已被删除(无限循环,没有副作用)。如果发生这种情况,a_function将立即返回。 -
我认为这可能是我们看到的原因 - "...调度程序通过随机提高就绪线程的优先级来解决这个问题..." docs.microsoft.com/en-us/windows/win32/procthread/… 线程
B正在得到提升,当A到达它的时间片线程的末尾时,B因为它的优先级提升而开始运行。
标签: c++ windows multithreading winapi