pthreads: допустимое количество потоков - PullRequest
2 голосов
/ 02 августа 2010

Я уже несколько дней работаю над небольшой программой на C, которая использует pthreads. Я провел более или менее весь вчера в поисках тупиковой ошибки, но теперь я обнаружил, что проблема на самом деле не в тупиковой ошибке. Следующий фрагмент кода имеет точно такую ​​же проблему.

#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#define NTHREADS 507

pthread_mutex_t runningThreadsMutex;
pthread_cond_t runningThreadsCond;
int runningThreads = 0;

void* HelloWorld(void* arg) {
  sleep(1);

  pthread_mutex_lock(&runningThreadsMutex);
  runningThreads--;
  printf("End thread %d\n", runningThreads);
  pthread_cond_signal(&runningThreadsCond);
  pthread_mutex_unlock(&runningThreadsMutex);

  return NULL;
}

int main() {
  pthread_t thread;

  pthread_mutex_init(&runningThreadsMutex, NULL);
  pthread_cond_init(&runningThreadsCond, NULL);

  for (int i = 0; i < NTHREADS; ++i) {
    pthread_mutex_lock(&runningThreadsMutex);
    printf("Create thread %d\n", runningThreads++);
    pthread_mutex_unlock(&runningThreadsMutex);
    pthread_create(&thread, NULL, HelloWorld, NULL);
  //  pthread_detach(thread);
  }

  pthread_mutex_lock(&runningThreadsMutex);
  while(runningThreads > 0) {
    pthread_cond_wait(&runningThreadsCond, &runningThreadsMutex);
  }
  pthread_mutex_unlock(&runningThreadsMutex);
  return 0;
}

Кажется, что приведенный выше код прекрасно работает на моем ноутбуке (64-битной машине Linux) для NTHREADS <506. В этом случае он печатает что-то вроде этого: </p>

Create thread 0
Create thread 1
.
.
.
Create thread 505
End thread 505
End thread 504
.
.
.
End thread 0

И заканчивается как следует. Однако, если я использую NTHREADS> = 506, например, NTHREADS = 510 я получаю

Create thread 0
Create thread 1
.
.
.
Create thread 509
End thread 509
End thread 508
.
.
.
End thread 4

, где он останавливается, никогда не заканчивая. Таким образом, кажется, что последние четыре (510-506 = 4) потока никогда не завершаются (или вообще не запускаются?).

Я пробовал этот код также на старой 32-битной машине Linux. Там я получаю такое же поведение, за исключением того, что оно хорошо работает для NTHREADS <382, но не для NTHREADS> = 382 (вместо 506).

Когда я гуглил решение, я также нашел этот вопрос: http://bytes.com/topic/c/answers/728087-pthreads-limit,, где у кого-то возникает такая же проблема при использовании pthread_join (что может быть более естественно при работе с pthreads), но они не приносят никакой пользы объяснение.

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

Ответы [ 2 ]

5 голосов
/ 27 сентября 2010

Вам необходимо проверить возвращаемое значение для pthread_create.Если он не равен нулю, функция не смогла создать поток.Типичная проблема - нехватка памяти для стеков новых потоков.Например, при стеке 1 МБ на поток системе потребуется 510 МБ свободной памяти для запуска 510 потоков.

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

4 голосов
/ 16 октября 2010

Добавив ответ Энтони, вы можете сбросить распределение стека для ваших потоков, используя следующий фрагмент кода:

pthread_attr_t threadAttr;
size_t threadStackSize = 65536;   // this is the stack size in bytes, 
                                  // must be over 16384 for Linux 
pthread_attr_init(threadAttr);
pthread_attr_setstacksize(&threadAttr,threadStackSize);

    if( pthread_create(&threadId,&threadAttr,funcn,NULL) != 0 )
    {
        printf("Couldn't create thread\n");
        exit(1);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...