Почему win api thread выполняет функцию, а стандартная - нет? - PullRequest
0 голосов
/ 13 марта 2019

У меня 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 thread показывает, что в начале подсчета записей в приложенииравно 10, поэтому if(nextEntryCount < entryCount) верно, и функция может быть выполнена.В начале потока Std имеет счетчик записей 0, поэтому if(nextEntryCount < entryCount) не соответствует истине, и функция не может быть выполнена.

Почему это так?

Нажатие строк перед созданием потока 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

Почему, используя стандартный поток, только один поток сделал всю работу?

1 Ответ

6 голосов
/ 13 марта 2019

t.join() заставляет вас блокировать, пока не закончится t. CloseHandle(threadHandle) не имеет такого же эффекта (закрывает дескриптор, но не ожидает в потоке).

Если вы хотите, чтобы std::thread соответствовал потокам WinAPI, создайте их все до join любого из них. Самым простым решением было бы отказаться от владения потоком, не дожидаясь его, заменив t.join() на t.detach().

...