我有15个线程,我想执行我推送的10个函数。我现在不关心保护它,只是想知道为什么win api执行功能,但是std没有。
代码或多或少来自手工制作的英雄日123
struct WorkQueueEntry
{
char* stringToPrint;
};
static uint32 nextEntryToDo;
static uint32 entryCount;
WorkQueueEntry entries[256];
inline void PushString(const char* string)
{
WorkQueueEntry* entry = entries + entryCount++;
entry->stringToPrint = const_cast<char*>(string);
}
struct ThreadInfo
{
int logicalThreadIndex;
};
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
printf("entry count %i, nextEntryToDo %i\n", entryCount, nextEntryToDo);
ThreadInfo* threadInfo = (ThreadInfo*)lpParameter;
for(;;) {
if(nextEntryToDo < entryCount) {
WorkQueueEntry* entry = entries + nextEntryToDo++;
char buffer[256];
sprintf_s(buffer, "Thread %u: %s", threadInfo->logicalThreadIndex, entry->stringToPrint);
printf(buffer);
}
}
}
在主要的某个地方
#define WinThread
ThreadInfo threadInfo[5];
for(int i = 0; i < _ARRAYSIZE(threadInfo); ++i) {
ThreadInfo* info = threadInfo + i;
info->logicalThreadIndex = i;
#ifdef WinThread
{
DWORD threadID;
HANDLE threadHandle = CreateThread(0, 0, ThreadProc, info, 0, &threadID);
CloseHandle(threadHandle);
}
#else
{
std::thread t(ThreadProc, info);
t.join();
}
#endif
}
PushString("String 0\n");
PushString("String 1\n");
PushString("String 2\n");
PushString("String 3\n");
PushString("String 4\n");
PushString("String 5\n");
PushString("String 6\n");
PushString("String 7\n");
PushString("String 8\n");
PushString("String 9\n");
win api线程显示,在应用程序输入计数的开头是10,所以if(nextEntryCount < entryCount)
是真的,功能可以完成。标准线程在开头有条目0,所以if(nextEntryCount < entryCount)
不是真的,并且func不能完成。
这是为什么?
在创建std线程之前推送字符串会修复它,但不完全正确。
现在它看起来像这样:
//#define WinThread
PushString("String 0\n");
PushString("String 1\n");
PushString("String 2\n");
PushString("String 3\n");
PushString("String 4\n");
PushString("String 5\n");
PushString("String 6\n");
PushString("String 7\n");
PushString("String 8\n");
PushString("String 9\n");
ThreadInfo threadInfo[5];
for(int i = 0; i < _ARRAYSIZE(threadInfo); ++i) {
ThreadInfo* info = threadInfo + i;
info->logicalThreadIndex = i;
#ifdef WinThread
{
DWORD threadID;
HANDLE threadHandle = CreateThread(0, 0, ThreadProc, info, 0, &threadID);
CloseHandle(threadHandle);
}
#else
{
std::thread t(ThreadProc, info);
t.join();
}
#endif
}
入口计数在开头是10,如果(nextEntryCount <entryCount)为真,那么func可以完成,但它打印的工作只由索引为0的线程完成。
为什么,使用标准线程,只有一个线程完成了所有工作?
t.join()
让你阻止,直到t
完成。 CloseHandle(threadHandle)
没有相同的效果(它关闭句柄但不等待线程)。
如果你想让std::thread
匹配WinAPI线程,请在join
ing之前创建它们。最简单的解决方案是通过用t.join()
替换t.detach()
来放弃线程的所有权而无需等待它。