为什么win api线程执行函数,但标准线程没有?

问题描述 投票:0回答:1

我有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的线程完成。

为什么,使用标准线程,只有一个线程完成了所有工作?

c++ multithreading winapi std
1个回答
6
投票

t.join()让你阻止,直到t完成。 CloseHandle(threadHandle)没有相同的效果(它关闭句柄但不等待线程)。

如果你想让std::thread匹配WinAPI线程,请在joining之前创建它们。最简单的解决方案是通过用t.join()替换t.detach()来放弃线程的所有权而无需等待它。

© www.soinside.com 2019 - 2024. All rights reserved.