Сделайте так, чтобы все потоки помещали свои результаты в один непрерывный вектор, как и раньше.Вы должны убедиться, что каждый поток обращается только к тем частям вектора, которые отделены от других.Пока это так (что должно быть независимо - вы не хотите генерировать один и тот же вывод дважды), каждый по-прежнему работает с памятью, отделенной от других, и вам не нужна блокировка (и т. Д.)чтобы вещи работали.Однако вам необходимо / нужно убедиться, что вектор для результата имеет правильный размер для всех результатов первым - несколько потоков пытаются (например) вызвать resize()
или push_back()
для вектора . посеять хаос в спешке (не говоря уже о том, чтобы вызвать копирование, которого вы явно хотите здесь избежать).
Редактировать: Как отметил Билли О'Нил, обычный способ сделать это - пройтиуказатель на каждую часть вектора, где каждый поток будет размещать свой вывод.Ради аргумента давайте предположим, что мы используем std::vector<std::vector<POINT> >
, упомянутый в качестве оригинальной версии вещей.На данный момент я собираюсь пропустить детали создания потоков (тем более, что это зависит от системы).Для простоты я также предполагаю, что количество генерируемых кривых является точным кратным числу потоков - в действительности, кривые не будут делиться точно равномерно, поэтому вам придется «выдумать»рассчитывать на одну нить, но это на самом деле не имеет отношения к рассматриваемому вопросу.
std::vector<USERPOINT> inputs; // input data
std::vector<std::vector<POINT> > outputs; // space for output data
const int thread_count = 4;
struct work_packet { // describe the work for one thread
USERPOINT *inputs; // where to get its input
std::vector<POINT> *outputs; // where to put its output
int num_points; // how many points to process
HANDLE finished; // signal when it's done.
};
std::vector<work_packet> packets(thread_count); // storage for the packets.
std::vector<HANDLE> events(thread_count); // storage for parent's handle to events
outputs.resize(inputs.size); // can't resize output after processing starts.
for (int i=0; i<thread_count; i++) {
int offset = i * inputs.size() / thread_count;
packets[i].inputs = &inputs[0]+offset;
packets[i].outputs = &outputs[0]+offset;
packets[i].count = inputs.size()/thread_count;
events[i] = packets[i].done = CreateEvent();
threads[i].process(&packets[i]);
}
// wait for curves to be generated (Win32 style, for the moment).
WaitForMultipleObjects(&events[0], thread_count, WAIT_ALL, INFINITE);
Обратите внимание, что хотя мы должны быть уверены, что вектор outputs
не будет изменен при работе с несколькими потокамиотдельные векторы точек в выходах могут быть, потому что каждый из них когда-либо будет затронут только одним потоком за раз.