Многопоточность: Как обработать данные в векторе, в то время как вектор населяется?

StackOverflow https://stackoverflow.com/questions/3681823

Вопрос

У меня есть однопоточное приложение Linux, которое я хотел бы сделать параллельно. Он читает файл данных, создает объекты и помещает их в вектор. Затем он вызывает компетентный метод (0,5 секунды +) на каждом объекте. Я хочу вызвать метод параллельно с созданием объекта. Пока я посмотрел на Qt и TBB, я открыт для других вариантов.

Я планировал начать нить (ы), пока вектор был пустым. Каждый позвонил бы makeSolids (ниже), который имеет цикл, который будет работать до тех пор, пока justpdone == true и все объекты в векторе были обработаны. Тем не менее, я N00B, когда дело доходит до резьбы, и я искал готовое решение.

QtConcurrent::map(Iter begin,Iter end,function()) Выглядит очень легко, но я не могу использовать его на векторе, который меняется в размере, может ли я? И как бы я сказал ему ждать больше данных?

Я также посмотрел на TBB Intel, но это выглядело, как моя главная тема, остановная, если бы я использовал parallel_for или parallel_while. Отказ Это воняет, поскольку был рекомендован их менеджер памяти (открытый MMGT Cascade имеет плохую производительность при многопоточке).

/**intended to be called by a thread
\param start the first item to get from the vector
\param skip how many to skip over (4 for 4 threads)
*/
void g2m::makeSolids(uint start, uint incr) {
  uint curr = start;
  while ((!interpDone) || (lineVector.size() > curr)) {
    if (lineVector.size() > curr) {
      if (lineVector[curr]->isMotion()) {
        ((canonMotion*)lineVector[curr])->setSolidMode(SWEPT);
        ((canonMotion*)lineVector[curr])->computeSolid();
      }
      lineVector[curr]->setDispMode(BEST);
      lineVector[curr]->display();

      curr += incr;
    } else {
      uio::sleep(); //wait a little bit for interp
    }
  }
}

Редактировать: Чтобы обобщить, каков самый простым способом обработки вектора одновременно, что основной поток заполняет вектор?

Это было полезно?

Решение

Трудно сказать, если вы думаете об этой проблеме глубоко, и есть больше, чем вы пропускаете, или если вы просто думаете об этом, или если вы просто опасаетесь потокости.

Чтение файла и создание объектов быстро; Один метод медленный. Зависимость каждым последовательным CTOR зависит от результата предыдущего ЦТОР - немного странно - но в противном случае нет проблем целостности данных, поэтому, похоже, нет ничего, что необходимо защищать Mutexes и такими.

Почему это сложнее, чем что-то вроде этого (в сыром псевдокоде):

while (! eof)
{
    readfile;
    object O(data);
    push_back(O);
    pthread_create(...., O, makeSolid);
}


while(x < vector.size())
{
    pthread_join();
    x++;
}

Если вы не хотите зацикливаться на присоединениях в своем главе, затем нерените нити, чтобы дождаться их, передавая вектор TID.

Если количество созданных объектов / потоков безумно, используйте пул резьбы. Или поставить счетчик - это цикл создания для ограничения количества потоков, которые могут быть созданы до подключения.

Другие советы

Во-первых, чтобы воспользоваться резьбой, вам нужно найти аналогичные медленные задачи для каждого потока. Вы сказали, что ваша обработка для каждого объекта занимает .5s +, сколько времени ваше создание чтения файлов / объектов? Это может быть легко доливая или тысячная часть этого времени, и в этом случае ваш многопоточный подход собирается производить нелюбиемое преимущество. Если это так, (да, я отвечу на ваш оригинальный вопрос в ближайшее время, если она не стоит), тогда подумайте о одновременном обработке нескольких объектов. Учитывая вашу обработку, требуется довольно некоторое время, создание потока накладные расходы не являются ужасно значительными, поэтому вы можете просто иметь основной материал для чтения / создания объектов создавать новую резьбу и направлять ее при вновь созданном объекте. Основная нить затем продолжает чтение / создание последующих объектов. Как только все объекты будут считываться / созданы, и все потоки обработки запускаются, основной нитью «объединяется» (ждет) рабочие потоки. Если это создаст слишком много потоков (тысячи), затем поместите ограничение на то, насколько далеко допускается основная нить, чтобы получить: он может прочитать / создавать 10 объектов, затем соедините 5, затем прочитайте / создать 10, присоединяйтесь к 10, прочитайте / создать 10, соедините 10 и т. Д. До завершения.

Теперь, если вы действительно хотите, чтобы прочитать / создать, чтобы быть параллельным с обработкой, но обработка должна быть сериализована, то вы все равно можете использовать вышеуказанный подход, но присоединиться после каждого объекта. Это рода странно, если вы разрабатываете это только с таким подходом, но хорошо, потому что вы можете легко экспериментировать с параллелизмом обработки объекта выше.

В качестве альтернативы, вы можете использовать более сложный подход, который просто включает в себя основную нить (чтобы ОС создает, когда ваша программа запускается), и один работник, который должен начать основной поток. Они должны быть скоординированы с помощью Mutex (переменная, обеспечивающая взаимно эксклюзивную, что означает не одновременно, доступ к данным) и переменную условия, которая позволяет рабочему потоку эффективно блокировать до тех пор, пока основной нить не предоставит больше. Условия - переменная METEX и условие - это стандартные условия в потоке POSIX, которые использует Linux, поэтому следует использовать в объяснении конкретных библиотек, которые вы заинтересованы в. Суммара, рабочая нить ждет до тех пор, пока основной прочитан / создает нить Распространяет его сигнал пробуждения, указывающий, что другой объект готов к обработке. Вы можете захотеть иметь счетчик с индексом последнего полностью созданного, готового для обработки объекта, поэтому рабочий ниток может поддерживать его количество обработанных объектов и перемещается вдоль готовых, прежде чем еще раз проверять переменную условию.

@Caleb: совсем - возможно, я должен был подчеркнуть активный потоки. Тема GUI всегда должна считаться одним.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top