LINUX.ORG.RU

[Потоки] [pthread_create] Минимальный пример. Текут дескрипторы и память.

 


0

1


Начал я тут разбираться с потоками. Нужно мне запускать кучу коротких потоков, и не дожидаясь их окончания дальше продолжать программу, запуская по ходу другие потоки.

И тут я наткнулся на то, что потоки вроде и завершаются, но не выгружаются из памяти. В результате течет память, а где-то на ~380-м создаваемом потоке функция pthread_create() возвращает ошибку 11.

Вот минимальный пример. Компилирую командой

g++ -L/usr/lib -x c++ -o sample sample.cpp -lm -lpthread

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define SLEEP1 25000
#define SLEEP2 60000

static void *threadFunc(void *arg);

int main (int argc, char *argv[]) 
{
 for(int iteration=1; iteration<1000000; iteration++)
  {
   pthread_t thread;
   int result=pthread_create(&thread, NULL, threadFunc, (void*)iteration);
 
   if(result != 0) 
    {
     printf("Creating thread false. Error: %d\nPress enter to exit\n", result);
     scanf("> \n");
     exit(1);
    }
  
   usleep(SLEEP1);
  }

 exit(0);
}


static void *threadFunc(void *arg)
{ 
 int iteration = (int) arg;

 printf("Thread %d start\n", iteration);
 usleep(SLEEP2);
 printf("Thread %d end\n", iteration);

 return NULL;
}

Пробовал добавлять в конец функции threadFunc() перед return NULL; команду pthread_exit(NULL);. Поведение то же самое, память течет, новый поток перестает создаваться на ~380-й итерации.

В чем тут проблема, как модифицировать этот пример чтобы он обрабатывал все итерации, и не текла память?

man pthread_create:

A thread may either be joinable or detached. If a thread is joinable, then another thread can call pthread_join(3) to wait for the thread to terminate and fetch its exit status. Only when a terminated joinable thread has been joined are the last of its resources released back to the system. When a detached thread terminates, its resources are automatically released back to the system: it is not possible to join with the thread in order to obtain its exit status. Making a thread detached is useful for some types of daemon threads whose exit status the application does not need to care about. By default, a new thread is created in a joinable state, unless attr was set to create the thread in a detached state (using pthread_attr_setdetachstate(3)).

А вообще, может тебе стоит еще подумать о пуле потоков - я как-то сомневаюсь, что тебе реально нужно одновременно держать тучу потоков.

Pavval ★★★★★
()
Ответ на: комментарий от AptGet

Атлично, спасибо.

Новый исправленный код, чтоб самому не забыть:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#define SLEEP1 25000
#define SLEEP2 60000

static void *threadFunc(void *arg);

int main (int argc, char *argv[]) 
{
 // Настройка атрибутов потока
 pthread_attr_t threadAttr; 
 pthread_attr_init(&threadAttr); 
 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); 
 
 for(int iteration=1; iteration<1000000; iteration++)
  {
   pthread_t thread;

   int result=pthread_create(&thread, &threadAttr, threadFunc, (void*)iteration);
 
   if(result != 0) 
    {
     printf("Creating thread false. Error: %d\nPress enter to exit\n", result);
     scanf("> \n");
     exit(1);
    }
  
   usleep(SLEEP1);
  }

 exit(0);
}


static void *threadFunc(void *arg)
{ 
 int iteration = (int) arg;

 printf("Thread %d start\n", iteration);
 usleep(SLEEP2);
 printf("Thread %d end\n", iteration);

 pthread_exit(NULL);

 return NULL;
}
webhamster
() автор топика
Ответ на: комментарий от webhamster

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

velikS
()

потоки вроде и завершаются, но не выгружаются из памяти

1. создавать их detached или
2. вызывать pthread_join() в main после окончания работы потока.

mi_estas
()
Ответ на: комментарий от webhamster

>printf(«Creating thread false.

Creating thread false

Ну нельзя же так.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.