CreateThread и dwStackSize
От: found Россия ak239.ru
Дата: 24.02.12 21:20
Оценка: 5 (2)
Здравствуйте.

В Университете задали лабораторную работу, в процессе выполнения которой необходимо создать, как можно больше потоков с помощью функции CreateThread.
(Отлично осознаю, что задача абсолютно искусственна и при реальной необходимости лучше воспользоваться Threadpool, либо IO)

Первое ограничение на количество потоков накладывает отношение размера адресного пространства всего потока к размеру стека процесса. Размер стека, создаваемого потока, задается отсюда:
To change the initially committed stack space, use the dwStackSize parameter of the CreateThread, CreateRemoteThread, or CreateFiber function. This value is rounded up to the nearest page.

Перелопатил множество статей о других ограничениях, лучшей из которых могу назвать следующую: "Преодолевая границы Windows: процессы и потоки". Она является переводом статьи Марка Руссиновича.

Но к необходимости много искать в интернете меня привел следующий код:
  ...
  for (int i = 0; i < MAX; i++){
    handles[i] = CreateThread(NULL, 1, ThreadProc, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION , NULL);
    ...


В моем представлении, которое опирается на документацию, в данном случае стек потока должен быть равен 64 КБ (размеру страницы в целевой системе — Windows 7 SP1). На деле же, согласно vmmap получается следующая картина:


Утилита, которая используется в статье Марка: testlimit с ключами -t -n(задает минимальный размер стека). Так же выделяет блоки стека по 1024 Кб, вместо 64 Кб.

В операционных системах Windows 2003 Server и Windows XP код, приведенный выше, создает потоки с размером стека равным 64 Кб. Для запуска в системы устанавливался пакет VS 2010 C++ Redist.

После тестирования в других ОС мне в голову пришла крамольная мысль об ошибке внутри самой Windows 7, потому что после ряда тестов, удалось выявить следующую закономерность:
Код:
    handles[i] = CreateThread(NULL, 4096, ThreadProc, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION , NULL);

Создает поток с размером стека в 1 Мб (значение по умолчанию).

Код:
    handles[i] = CreateThread(NULL, 4097, ThreadProc, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION , NULL);

Создает поток с размером стека в 64 Кб (ближайшая страница).

Дальнейшие опыты показали, что при значения dwStackSize 0 — применяется значение по умолчанию, от 1 до 4096 значение по умолчанию, от 4097 до 65536 — 64 Кб, при 65537 — 128 Кб. Что наталкивает на мысль об ошибке округления внутри функции, находящейся в ядре ОС, и отвечающей за создание потоков.

Резюмирую список вопросов:
1. Действительно ли при 0 < dwStackSize <= 64 Кб должно резервироваться 64 Кб?
2. Пакеты для Microsoft Visual C++ X Redistributable Package являются ли прослойкой между приложением и вызовом системных функций, либо же функции WinAPI, к примеру, CreateThread вызываются напрямую?
3. Если же имеет место ошибка в функции WinAPI, куда можно писать баг репорт?

Спасибо, за внимание. Мой первый пост на rsdn, выслушаю любую критику по оформлению.
createthread stack size winapi
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.