ждать неизвестного количества потоков, созданных CreateThread

0

Мне нужно создать неизвестное количество потоков, и в конце нужно ждать, пока все созданные потоки закончат свои задания. После поиска я мог подождать только некоторое количество созданных потоков, используя WaitForMultipleObjects(...) который ожидает указатель на массив дескрипторов созданных потоков. Следующий пример - пример сценария.

#include "stdafx.h"
#include <Windows.h>
#include <time.h>

FILE* fp;
time_t start;

struct mydata{
    int a, b;
};

void myFn(mydata* p)
{
    fprintf(fp, "a = %d\n", p->a);
    fprintf(fp, "b = %d\n", p->b);
    delete p;
}

bool condition()
{
     if(time(0) - start >= 1)
        return false;
     return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
    start = time(0);
    fopen_s(&fp, "outOfExe.txt", "w");
    mydata* dataToGive;
    int n = 0;
    while(condition())
    {
        n++;
        dataToGive = new mydata;
        dataToGive->a = 2*n;
        dataToGive->b = 4*n;
        HANDLE WINAPI handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)myFn, dataToGive, 0, NULL);
    }
}

Решение, о котором я мог думать, состоит в создании массива размера, равного количеству ядер в ЦП, и в любой момент времени выполняется с максимальным количеством этих потоков. Но для этого мне потребуется разработать механизм очередей и т.д. Есть ли способ подождать все созданные потоки, как показано в приведенном выше примере?

  • 0
    По какой причине вы не можете использовать массив (или std :: vector) для хранения дескрипторов? также почему бы не использовать std :: thread?
  • 0
    Я написал это как одно из решений - но мне было интересно, если это можно сделать без использования массива. И std :: thread не поддерживается в Visual C ++ 2008 (верно?)
Теги:
multithreading
visual-c++
visual-studio-2008

2 ответа

1
Лучший ответ

int threadCount, критический раздел, событие и WaitForSingleObject?

Заблокируйте CS, создайте свои потоки, нарисуйте threadCount, затем откройте CS и подождите события.

В функции/методе потока выполните свои действия, затем, в конце, заблокируйте CS, отмените threadCount. Если он равен 0, сообщите об этом событии. Разблокируйте CS и выйдите из потока.

Нет массива, нет вектора, нет, (нормальный), ограничение количества потоков.

  • 0
    Хотите объяснить "WaitForSingleObject?" Я понял, что нужно иметь общее количество потоков и увеличивать / уменьшать его, получая при этом блокировку. В конце основного потока просто цикл, пока счетчик не станет 0.
  • 2
    @BitManipulator Используйте CreateEvent в начале. Когда поток видит, что это последний, он сообщает о событии с помощью SetEvent. Основной поток ждет, используя WaitForSingleObject, чтобы событие было сигнализировано.
Показать ещё 1 комментарий
2

Использование std::vector - это, безусловно, способ сделать и не требует очереди или имеет заданное количество ручек потоков, которые он может хранить. В приведенном ниже коде будут созданы все потоки, а затем дождаться завершения всех этих действий.

std::vector<HANDLE> threadHandles;
while(condition())
{
    n++;
    dataToGive = new mydata;
    dataToGive->a = 2*n;
    dataToGive->b = 4*n;
    HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)myFn, dataToGive, 0, NULL);
    if(handle != INVALID_HANDLE_VALUE)
    {
        threadHandles.push_back(handle);
    }
}

::WaitForMultipleObjects(threadHandles.size(), &threadHandles[0], TRUE, INFINITE);

Как заметил Мартин WaitForMultipleObjects ограничивает количество дескрипторов, на которые он может ждать до 64. Если вам нужно больше 64 потоков, это не сработает.

  • 0
    WFMO имеет ограничение в 64 ручки :(
  • 0
    в случае, если я использую векторы (или массив), я не должен сохранять количество потоков равным количеству ядер по соображениям эффективности?
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню