Задать вопрос

Как избавиться от ошибки при создании более N потоков с передачей в него структуры?

Есть структура, допустим
typedef struct {
	String a,b;
} ThreadData;

В структуре имеются типы: bool, String, int, vector(String), vector(int).
Создаю поток так:
for (int h = 0; h < count; h++) {
    //count это количество создаваемых потоков
    ThreadData *td = new ThreadData;
    /*заполняю структуру*/		
    td->NumberOfThread = h + 1;
    DWORD id;
    HANDLE thread = CreateThread(NULL, 0U, MainThread, (LPVOID)td, THREAD_PRIORITY_NORMAL, &id);
    CloseHandle(thread);
};

Функция потока:
DWORD WINAPI MainThread(LPVOID lpParameter) {
	ThreadData * td = (ThreadData*)lpParameter;
	/*какая-то операция с данными потоками*/
	delete td;
	ExitThread(0u);
	return 0;
}

Вместо CreateThread пробовал _beginthread, результат тот же, а именно: при создании 1400 потоков все работает хорошо, если создавать больше 1500, то софт крэшится. Бывает успевает вылезти ошибка "out of memory". при работе в 1400 потоков в диспетчере задач кушается около 100 МБ.
Личные замечания:
Если просто создавать структуры в цикле через new, не создавая новый поток, то все работает, можно создать и 100к экземпляров структуры.
Если не создавать структуру, а поднимать 100к потоков, не передавая в них ничего, то тоже потоки создаются и работают.
Если создавать эксземпляры структур и создавать потоки, но в поток ничего не передавать и в потоке ничего не создавать, то софт крэшится.
Подскажите в чем причина и как с этим бороться?
  • Вопрос задан
  • 351 просмотр
Подписаться 2 Оценить 2 комментария
Пригласить эксперта
Ответы на вопрос 2
gbg
@gbg Куратор тега C++
Любые ответы на любые вопросы
Выделяйте память сразу крупным блоком - это более выгодная стратегия, чем насилование кучи.
Ну и исключение при вызове new стоит все же ловить и обрабатывать.

Да и какой смысл создавать тысячи потоков, в то время, как машин более чем с парой сотен ядер пока не видать (да и то, на такие цифродробилки обычно не ставят прошивку от иксбокса - глючна-с).
Ответ написан
@Power
Думаю, вы банально упираетесь в размер памяти. Согласно MSDN, для каждого потока по умолчанию резервируется 1 МБ под стек. 1400 потоков -> 1400 МБ.
А тесты ваши не показательны, т.к. в текущем варианте каждый поток почти ничего не делает, и вполне может быть, что потоки успевают завершиться, пока вы создаёте новые. Таким образом, цикл может крутиться очень долго. Добавьте в функцию потока вызов Sleep на 24 часа и посмотрите, как изменятся результаты тестов.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы