pthread_create и EAGAIN - PullRequest
       24

pthread_create и EAGAIN

5 голосов
/ 26 декабря 2011

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

Что определяет ОС для предоставления EAGAIN при попытке создать поток с помощью pthread_create?Возможно ли, что незакрытые сокеты / дескрипторы файлов играют роль в создании этого EAGAIN (то есть они совместно используют одно и то же пространство ресурсов)?

И, наконец, есть ли инструмент для проверки использования ресурсов или любые функции, которыеиспользоваться, чтобы увидеть, сколько объектов pthread активно в данный момент?

Ответы [ 5 ]

9 голосов
/ 03 января 2012

Хорошо, нашел ответ.Даже если вызывается pthread_exit или pthread_cancel, родительский процесс все равно должен вызвать pthread_join для освобождения идентификатора pthread, который затем станет пригодным для повторного использования.

Помещение pthread_join (tid, NULL) в конец сделало свое дело.

edit (был не waitpid, а pthread_join)

4 голосов
/ 27 декабря 2011

На практике EAGAIN почти всегда связан с нехваткой памяти для процесса. Часто это связано с размером стека, выделенного для потока, который вы можете настроить с помощью pthread_attr_setstacksize(). Но существуют ограничения на количество процессов, которые вы можете запустить. Вы можете запросить жесткие и мягкие ограничения с помощью getrlimit(), используя RLIMIT_NPROC в качестве первого параметра.

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

Открытые сокеты или другие файловые дескрипторы не должны вызывать сбой pthread_create(). Если бы вы достигли максимума для дескрипторов, вы бы уже потерпели неудачу перед созданием нового потока, и новый поток уже должен был бы быть успешно создан, чтобы открыть больше из них, и, следовательно, не мог завершиться ошибкой с EAGAIN.

1 голос
/ 05 октября 2016

Согласно моему наблюдению, если один из родительских процессов вызывает pthread_join (), и охлажденные процессы пытаются освободить поток, вызывая pthread_exit () или pthread_cancel (), тогда система не сможет правильно освободить этот поток. В этом случае, если pthread_detach () вызывается сразу после успешного вызова pthread_create (), тогда эта проблема решена. Снимок здесь -

err = pthread_create(&(receiveThread), NULL, &receiver, temp);
if (err != 0)
{
 MyPrintf("\nCan't create thread Reason : %s\n ",(err==EAGAIN)?"EAGAUIN":(err==EINVAL)?"EINVAL":(err==EPERM)?"EPERM":"UNKNOWN");
    free(temp);
}
else
{
    threadnumber++;
    MyPrintf("Count: %d Thread ID: %u\n",threadnumber,receiveThread);
    pthread_detach(receiveThread);
}
0 голосов
/ 18 апреля 2018

Возможный ответ на вопрос «есть ли инструмент для проверки использования ресурсов»? Может быть полезно ...

void printRlimit(const char *msg, int resource){
   struct rlimit rlim;
   getrlimit(resource, &rlim);
   printf("\n%s ", msg);
   printf("soft=");

   if (rlim.rlim_cur == RLIM_INFINITY)
       printf("infinite");
   else if (rlim.rlim_cur == RLIM_SAVED_CUR)
       printf("unrepresentable");
   else
       printf("%lld", (long long) rlim.rlim_cur);

   printf(" hard=");
   if (rlim.rlim_max == RLIM_INFINITY)
     printf("infinite\n");
   else if (rlim.rlim_max == RLIM_SAVED_MAX)
       printf("unrepresentable");
   else
       printf("%lld\n", (long long) rlim.rlim_max);
}

int main(){
   printRlimit("RLIMIT_AS", RLIMIT_STACK);
   printRlimit("RLIMIT_CORE", RLIMIT_CORE);
   printRlimit("RLIMIT_CPU", RLIMIT_CPU);
   printRlimit("RLIMIT_DATA", RLIMIT_DATA);
   printRlimit("RLIMIT_FSIZE", RLIMIT_FSIZE);
   printRlimit("RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
   printRlimit("RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
   printRlimit("RLIMIT_NPROC", RLIMIT_NPROC);
   printRlimit("RLIMIT_NICE", RLIMIT_NICE);
   printRlimit("RLIMIT_NOFILE", RLIMIT_NOFILE);
   printRlimit("RLIMIT_RSS", RLIMIT_RSS);
   printRlimit("RLIMIT_RTPRIO", RLIMIT_RTPRIO);
   printRlimit("RLIMIT_RTTIME", RLIMIT_RTTIME);
   printRlimit("RLIMIT_SIGPENDING", RLIMIT_SIGPENDING);
   printRlimit("RLIMIT_STACK", RLIMIT_STACK);
   return 0;
}
0 голосов
/ 05 ноября 2016

Другая потенциальная причина: у меня возникла эта проблема (EAGAIN на pthread_create), потому что я забыл вызвать pthread_attr_init на pthread_attr_t, с которой я пытался инициализировать поток.

...