2013-12-10 4 views
1

Я новичок здесь, и я надеюсь, что все делаю правильно.Какой поток заканчивается многопоточным?

Мне было интересно узнать, какой поток заканчивается после того, как он закончил работу с помощью команды WaitForMultipleObjects. В настоящее время у меня есть что-то вроде:

int checknum; 
int loop = 0; 
const int NumThreads = 3; 

HANDLE threads[NumThreads]; 

WaitForMultipleObjects(NumThreads, threads, false, INFINITE); 
threads[loop] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0); 

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

Я бы вложил остальную часть своего кода, но я уверен, что никто не нуждается во всех 147 строках. Я решил, что этого фрагмента будет достаточно.

ответ

2

Когда третий параметр равен false, WaitForMultipleObjects вернется, как только будет сигнализирован ЛЮБОЙ из объектов (ему не нужно ждать их всех).

И возвращаемое значение указывает, какой объект заставлял его возвращать. Это будет WAIT_OBJECT_0 для первого объекта, WAIT_OBJECT_0 + 1 для второго и т. Д.

+0

Мне понадобился только один поток, чтобы очистить его, прежде чем я смогу его повторно использовать. Как преобразовать WAIT_OBJECT в 0, 1 или 2, чтобы я мог просто сделать значение цикла равным этому, чтобы циклы могли продолжаться. Или есть способ проверить, свободен ли один из трех потоков и взять первый доступный? – Virlym

+0

Вы можете просто сказать 'int index = WaitForMultipleObjects (NumThreads, threads, false, INFINITE) - WAIT_OBJECT_0', но вам также следует проверить другие ошибки, указанные возвращаемым значением. –

+0

спасибо. Мне просто нужен способ узнать, какой поток был закончен, чтобы я мог его повторно использовать. Я делаю проверку ошибок до начала потока, поскольку поток - просто простая проверка числа. – Virlym

0

Я вдали от своего компилятора, и я не знаю IDE onlione, который работает с окнами, но вот приблизительное представление о том, что вам нужно делать.

const int NumThreads = 3; 
HANDLE threads[NumThreads]; 
//create threads here 
DWORD result = WaitForMultipleObjects(NumThreads, threads, false, INFINITE); 
if(result >= WAIT_OBJECT_0 && result - WAIT_OBJECT_0 < NumThreads){ 
    int index = result - WAIT_OBJECT_0; 
    if(!CloseHandle(Handles[index])){ //need to close to give handle back to system even though the thread has finished 
     DWORD error = GetLastError(); 
     //TODO handle error 
    } 
    threads[index] = CreateThread(0, 0, ThreadFunction, &checknum, 0, 0); 
} 
else { 
    DWORD error = GetLastError(); 
    //TODO handle error 
    break; 
} 

на работе мы делаем это несколько иначе. Мы создали библиотеку, которая обертывает все необходимые типы дескрипторов окон и проверки статических типов преформ (хотя операторы преобразования), чтобы убедиться, что вы не можете ждать IOCompletionPort с WaitForMultipleObjects (что недопустимо). Функция wait является вариационной, а не принимает массив ручек и его размер и специализируется с использованием SFINAE для использования WaitForSingleObject, когда есть только один. Он также принимает Lambdas в качестве аргументов и выполняет соответствующий в зависимости от сигнального события.

Это то, что он выглядит следующим образом:

Win::Event ev; 
Win::Thread th([]{/*...*/ return 0;}); 
//... 

Win::WaitFor(ev,[]{std::cout << "event" << std::endl;}, 
     th,[]{std::cout << "thread" << std::endl;}, 
     std::chrono::milliseconds(100),[]{std::cout << "timeout" << std::endl;}); 

Я очень рекомендую этот тип упаковки, потому что в конце дня, компилятор оптимизирует его в тот же код, но вы не можете сделать почти столько же ошибки.

Смежные вопросы