С++ pthread ограничивает количество потоков

Я попытался использовать pthread, чтобы выполнить какую-то задачу быстрее. У меня есть тысячи файлов (в аргументах) для обработки, и я хочу много раз создавать лишь небольшое количество потоков.
Вот мой код:

void callThread(){
    int nbt = 0;
    pthread_t *vp = (pthread_t*)malloc(sizeof(pthread_t)*NBTHREAD);
    for(int i=0;i<args.size();i+=NBTHREAD){
        for(int j=0;j<NBTHREAD;j++){
              if(i+j<args.size()){
                   pthread_create(&vp[j],NULL,calcul,&args[i+j]);   
                   nbt++;
              }
        }
        for(int k=0;k<nbt;k++){
              if(pthread_join(vp[k], NULL)){
                   cout<<"ERROR pthread_join()"<<endl;
              } 
        }
   }
}

Он возвращает ошибку, я не знаю, хороший ли это способ решить мою проблему. Все ресурсы находятся в args (векторе структуры) и являются независимыми.
Спасибо за помощь.


person user1788477    schedule 24.01.2013    source источник
comment
Он возвращает ошибку. Что это такое и какую ошибку выдает?   -  person NPE    schedule 24.01.2013
comment
чего вы надеетесь достичь с тысячами потоков?   -  person Sam Miller    schedule 24.01.2013
comment
Лучшей идеей было бы создать небольшой пул потоков, которые воздействуют на задания в очереди. Затем добавьте все файлы в очередь и позвольте потокам выбирать задания одно за другим до тех пор, пока работа не закончится.   -  person Martin York    schedule 24.01.2013
comment
Мне не нужны тысячи потоков, я просто хочу применить вычисление функции к каждой структуре в аргументах. Но эти структуры независимы, поэтому я хочу ускорить процесс.   -  person user1788477    schedule 24.01.2013
comment
@LokiAstari, я не знаю пул потоков, но думаю, это то, что я ищу. я попробую с ним   -  person user1788477    schedule 24.01.2013
comment
это работает с небольшим количеством потоков? Если это так, возможно, вы достигли предела количества процессов, которые вы можете запустить. Вы можете проверить, что это такое, с помощью ulimit -u.   -  person Gabriel Southern    schedule 24.01.2013
comment
Это просто означает запуск небольшого фиксированного количества потоков (это называется пулом). Затем потоки запускают функцию, которая в основном представляет собой цикл, в котором поток проверяет, есть ли работа. Если нет, то спит. Если есть работа, которую он берет, она выполняет работу, а затем возвращается в пул доступных потоков. Это может помочь: stackoverflow.com/a/5799978/14065   -  person Martin York    schedule 24.01.2013


Ответы (2)


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

Пара советов, которые не упомянуты в этом посте:

  • Используйте std::thread::hardware_concurrency(), чтобы получить количество ядер.
  • Придумайте способ хранения задач, подсказка: std::packaged_task или что-то в этом роде, завернутое в класс, чтобы вы могли отслеживать такие вещи, как выполнение задачи, или реализовать task.join().
  • Кроме того, здесь можно найти github с кодом его реализации и некоторыми дополнительными вещами, такими как поддержка std::future.
person Edward A    schedule 24.01.2013

Вы можете использовать семафор для ограничения количества параллельных потоков, вот псевдокод:

Semaphore S = MAX_THREADS_AT_A_TIME  //  Initial semaphore value
declare handle_array[NUM_ITERS];

for(i=0 to NUM_ITERS)
{
wait-while(S<=0);
Acquire-Semaphore;  //  S--

handle_array[i] = Run-Thread(MyThread);

}

for(i=0 to NUM_ITERS)
{
Join_thread(handle_array[i])
Close_handle(handle_array[i])
}


MyThread()
{
mutex.lock

critical-section

mutex.unlock

release-semaphore // S++
}
person StackHeapCollision    schedule 24.01.2013