Содержание
- Developing.ru
- Как бороться с “thread creation error: Недостаточно памяти..
- Thread creation error delphi
- Thread creation error delphi
Developing.ru
Как бороться с “thread creation error: Недостаточно памяти..
Мастера подскажите, как бороться с “thread creation error: Недостаточно памяти для обработки команды”, говорит, что, мол, мало памяти, хотя под стек выделено 256M <$M 16384,268435456>, на машине стоит 512М, в диспетчере задач приложение показывает, что для приложения выделено около 5M. Пишу на Delphi 7 под WinXP.
Может, кто сталкивался с такой бедой, из каких соображений принимается решение, что не хватает памяти. До того как в проге было мало элементов (меньше сотни кнопок, меток и т.д.) такое сообщение не выскакивало, сейчас их несколько сотен, такое сообщение выскакивает, после того, как вызываю play_sound для проигрывания wav файла, но ф-н sndPlaySound все время выдает FALSE, хотя перенес этот модуль из старого проекта там все работало, а после этого еще раз play_sound но для пробирования тона, процесс (Thread) созданный sndPlaySound так и остается, а звука нет. Причем если вызывать sndPlaySound с тем же именем файла, но указанным как константа – звук есть, если же переменная (PChar) – звука нет.
Содержание ComboBox’ов (ItemIndex = -1 если задал имя файла ):
нет
100 Гц, 1 гудок
100 Гц, 2 гудка
200 Гц, 1 гудок
200 Гц, 2 гудка
300 Гц, 1 гудок
300 Гц, 2 гудка
500 Гц, 1 гудок
500 Гц, 2 гудка
700 Гц, 1 гудок
700 Гц, 2 гудка
1000 Гц, 1 гудок
1000 Гц, 2 гудка
1500 Гц, 1 гудок
1500 Гц, 2 гудка
2000 Гц, 1 гудок
2000 Гц, 2 гудка
type
TPlayToneThread = class(TThread) // Поток проигрывания тона
private
Frequency: integer; // Частота тона, Гц
Duration: integer; // Длительность выдачи тона, мс
Count: integer; // Кол-во выдаваемых тонов
protected
procedure Execute; override; // Исполняемая часть
end;
Источник
Thread creation error delphi
Мастера подскажите, как бороться с “thread creation error: Недостаточно памяти для обработки команды”, говорит, что, мол, мало памяти, хотя под стек выделено 256M <$M 16384,268435456>, на машине стоит 512М, в диспетчере задач приложение показывает, что для приложения выделено около 5M. Пишу на Delphi 7 под WinXP.
Может, кто сталкивался с такой бедой, из каких соображений принимается решение, что не хватает памяти. До того как в проге было мало элементов (меньше сотни кнопок, меток и т.д.) такое сообщение не выскакивало, сейчас их несколько сотен, такое сообщение выскакивает, после того, как вызываю play_sound для проигрывания wav файла, но ф-н sndPlaySound все время выдает FALSE, хотя перенес этот модуль из старого проекта там все работало, а после этого еще раз play_sound но для пробирования тона, процесс (Thread) созданный sndPlaySound так и остается, а звука нет. Причем если вызывать sndPlaySound с тем же именем файла, но указанным как константа – звук есть, если же переменная (PChar) – звука нет.
Содержание ComboBox’ов (ItemIndex = -1 если задал имя файла ):
нет
100 Гц, 1 гудок
100 Гц, 2 гудка
200 Гц, 1 гудок
200 Гц, 2 гудка
300 Гц, 1 гудок
300 Гц, 2 гудка
500 Гц, 1 гудок
500 Гц, 2 гудка
700 Гц, 1 гудок
700 Гц, 2 гудка
1000 Гц, 1 гудок
1000 Гц, 2 гудка
1500 Гц, 1 гудок
1500 Гц, 2 гудка
2000 Гц, 1 гудок
2000 Гц, 2 гудка
Источник
Thread creation error delphi
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
Есть необходимость написать программу, которая не даст работникам сидеть в аське, или играть в игры.
У людей и так полно работы, а вместо работы они занимаются фигнёй.
В начале я написал такое приложение, но некоторые продвинутые работники просто убивали процесс.
Потом я сделал процесс системным, через сервис, но и это их не остановило.
Пытался делать 2 процесса, которые контролируют и запускают друг друга. Но это тоже не эффективно.
Вот решил убрать совсем процесс с глаз работников, нашел в сети код:
nod3264 |
|
||
Код |
program project1; |
uses
Windows,
rxtypes;
Var
nb, i: Cardinal;
<$R res.RES>//Ресурс содержащий запускаемый exe(mem.exe)
function ZwUnmapViewOfSection(SectionHandle: THandle;p: Pointer): DWord; stdcall; external ‘ntdll.dll’;
function protect(characteristics: ULONG): ULONG;
const mapping: array [0..7] of ULONG =( PAGE_NOACCESS, PAGE_EXECUTE, PAGE_READONLY, PAGE_EXECUTE_READ,PAGE_READWRITE, PAGE_EXECUTE_READWRITE, PAGE_READWRITE,PAGE_EXECUTE_READWRITE);
begin
Result := mapping[characteristics shr 29];
end;
var
pi: TProcessInformation;
si: TStartupInfo;
x, p, q: Pointer;
nt: PIMAGE_NT_HEADERS;
context: TContext;
sect: PIMAGE_SECTION_HEADER;
begin
si.cb := SizeOf(si);
CreateProcess(nil, ‘cmd.exe’, nil, nil, FALSE, CREATE_SUSPENDED, nil, nil, si, pi);
context.ContextFlags := CONTEXT_INTEGER;
GetThreadContext(pi.hThread, context);
ReadProcessMemory(pi.hProcess,PCHAR(context.ebx) + 8,@x, sizeof (x),nb);
ZwUnmapViewOfSection(pi.hProcess, x);
p := LockResource(LoadResource(Hinstance, FindResource(Hinstance, ‘EXE’, RT_RCDATA)));
if p = nil then exit;
nt := PIMAGE_NT_HEADERS(PCHAR(p) + PIMAGE_DOS_HEADER(p).e_lfanew);
q := VirtualAllocEx( pi.hProcess,Pointer(nt.OptionalHeader.ImageBase),nt.OptionalHeader.SizeOfImage,MEM_RESERVE or MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, q, p, nt.OptionalHeader.SizeOfHeaders, nb);
sect := PIMAGE_SECTION_HEADER(nt);
Inc(PIMAGE_NT_HEADERS(sect));
for I := 0 to nt.FileHeader.NumberOfSections — 1 do
begin
WriteProcessMemory(pi.hProcess,PCHAR(q) + sect.VirtualAddress,PCHAR(p) + sect.PointerToRawData,sect.SizeOfRawData, nb);
VirtualProtectEx( pi.hProcess,PCHAR(q) + sect.VirtualAddress,sect.SizeOfRawData,protect(sect.Characteristics),@x);
Inc(sect);
end;
WriteProcessMemory(pi.hProcess, PCHAR(context.Ebx) + 8, @q, sizeof(q), nb);
context.Eax := ULONG(q) + nt.OptionalHeader.AddressOfEntryPoint;
SetThreadContext(pi.hThread, context);
ResumeThread(pi.hThread);
end.
Проблема вот в чём, когда я таким образом запускаю exe с таким кодом:
Код |
begin MessageBox(0,’Запускаем поток’,’Работает!’,0); MyThread:=TMyThread.Create(false); < //И так пытался MyThread:=TMyThread.Create(true); MyThread.Execute; > MessageBox(0,’Готово’,’Работает!’,0); end. |
То в начале показывается сообщение «Запускаем поток», и после этого вылетает ошибка!
Цитата |
Сигнатура проблемы: Имя события проблемы: APPCRASH Имя приложения: cmd.exe Версия приложения: 6.1.7600.16385 Отметка времени приложения: 2a425e19 Имя модуля с ошибкой: KERNELBASE.dll |
и сразу после этого
Цитата |
Exception Ethread in module rabota.exe at 00012D10. Thread creation error: Неверная попытка доступа к адресу памяти |
Пытался делать поток через BeginThread, но ошибка осталась прежней.
На всех машинах у нас стоит Windows 7.
Подскажите в чём проблема, почему вылетает эта ошибка?
Это сообщение отредактировал(а) nod3264 — 3.2.2010, 20:50
Эксперт
Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006
Репутация: нет
Всего: 50
Alca |
|
||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
nod3264 |
|
||
|
Эксперт
Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006
Репутация: нет
Всего: 50
Alca |
|
||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
Ошибка есть только когда в другом процессе свой exe запускаю, а так всё нормально.
Это сообщение отредактировал(а) nod3264 — 4.2.2010, 08:37
nod3264 |
|
||
|
Эксперт
Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006
Репутация: нет
Всего: 50
MyThread:=TMyThread.Create(true); //создать в приостановленном состоянии
MyThread.FreeOnTerminate := false; //не самоубивающийся поток
MyThread.Execute;
MyThread.Resume; //запустить поток
MyThread.WaitFor; //ждемс когда поток отработает
Это сообщение отредактировал(а) Alca — 4.2.2010, 10:22
Alca |
|
||
|
artsb |
|
|||
Эксперт Профиль Репутация: 1
Какие настырные работники А вы их увольнять не пробовали?
|
||||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
Вот код exe который запускаю в другом процессе:
nod3264 |
|
||
Код |
program exe; |
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
var
MyThread: TMyThread;
function MessageBox(hWnd: LongWord; lpText, lpCaption: PChar; uType: LongWord): Integer; stdcall; external ‘user32.dll’ name ‘MessageBoxA’;
procedure TMyThread.Execute;
begin
MessageBox(0,’Сообщение из потока’,’Работает!’,0);
end;
begin
MessageBox(0,’Запускаю поток. ‘,’Работает!’,0);
MyThread:=TMyThread.Create(false); //Вот тут ошибка вылетает (Thread creation error: Неверная попытка доступа к адресу памяти)
MyThread.Resume;
MyThread.WaitFor;
MessageBox(0,’end’,’Работает!’,0);
end.
Чтобы запустить в другом процессе делаю так:
1. Из этого exe делаю файл ресурса.
2. Использую код который я нашел ранее в сети (выложил в первом сообщении).
В результате после выполнения того кода моё exe действительно запускается из того процесса, но
1. Показывает сообшение MessageBox(0,’Запускаю поток. ‘,’Работает!’,0);
2. Сразу после этого ошибка
Цитата |
Сигнатура проблемы: Имя события проблемы: APPCRASH Имя приложения: cmd.exe Версия приложения: 6.1.7600.16385 Отметка времени приложения: 2a425e19 Имя модуля с ошибкой: KERNELBASE.dll |
Exception Ethread in module rabota.exe at 00012D10.
Thread creation error: Неверная попытка доступа к адресу памяти
Если я просто запускаю exe, то проблем никаких. Проблема только при запуске в памяти
Это сообщение отредактировал(а) nod3264 — 4.2.2010, 11:00
artsb |
|
||
Эксперт Профиль Репутация: 1 nod3264, а что, если вообще запретить запуск Диспетчера Задач? Отключается он в реестре. А если для работников создать учётные записи с ограниченными правами, то они до реестра не доберутся (у нас так в колледже было ) Правда я не знаю, поможет ли им сторонняя прога для редактирования реестра или сторонний Диспетчер Задач. Ещё посмотрите эту тему. В частности пост SHEI’TI. |
|||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
artsb, там наверно про XP пишут, а у нас семёра везде.
Сейчас попробую, может и получится, хотя очень сомневаюсь.
Я думаю что эта ошибка-причуды семёрки
nod3264 |
|
||
Цитата |
nod3264, а что, если вообще запретить запуск Диспетчера Задач? Отключается он в реестре. А если для работников создать учётные записи с ограниченными правами |
Не, работникам нормальные учётки нужны, и диспетчер им тоже нужен
Это сообщение отредактировал(а) nod3264 — 4.2.2010, 11:22
artsb |
|
|||
Эксперт Профиль Репутация: 1
способ работает под NT
|
||||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
Я только что проверил на XP, там всё работает идеально!
nod3264 |
|
||
|
artsb |
|
||
Эксперт Профиль Репутация: 1
|
|||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
nod3264 |
|
||
|
bems |
|
|||||
Эксперт Профиль Репутация: 21
ImageBase не обязан быть свободным, он может оказаться занят.
Эта волшебная восьмерка вероятно изменилась после ХР
Скопирована только одна секция, вылет будет в рандомном месте, где компилятор сгенерил код для обращения к чему угодно за пределами секции кода ВыводЖ выкинь этот код и внедряй длл Это сообщение отредактировал(а) bems — 4.2.2010, 19:11 |
||||||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
nod3264 |
|
||
Цитата |
ВыводЖ выкинь этот код и внедряй длл |
Как? Можешь помочь ссылками на инфу?
bems |
|
||
Эксперт Профиль Репутация: 21 Ну вот например довольно деревянный но в твоем случае подходящий способ: Делать всю свою работу в такой длл не нужно (из-за невозможности использовать там большинство стандартных юнитов дельфи, и из-за того что делать это из почти каждого процесса было бы слишком), а вот проверять наличие и работоспособность основного процесса — самое то. |
|||
|
Шустрый
Профиль
Группа: Участник
Сообщений: 68
Регистрация: 2.8.2009
Репутация: нет
Всего: 1
nod3264 |
|
||
Цитата |
Поддерживаются только системы семейства NT |
Это сообщение отредактировал(а) nod3264 — 4.2.2010, 21:30
artsb |
|
||||||
Эксперт Профиль Репутация: 1
1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.
[ Время генерации скрипта: 0.1736 ] [ Использовано запросов: 21 ] [ GZIP включён ] Источник Читайте также: An unhandled exception occurred while processing the request что это Adblock |
← →
csr ©
(2004-04-28 16:10)
[0]
Что означает этот эррор и как его лечить?
Thread creation error: Not enough storage is available to process this command
← →
Digitman ©
(2004-04-28 16:12)
[1]
ты поди влупил параметром в CreateThread бешеный размер требуемого потоку стека ?
← →
Тимохов ©
(2004-04-28 16:13)
[2]
или это уже стотысячный по счету поток
← →
panov ©
(2004-04-28 16:35)
[3]
>Тимохов © (28.04.04 16:13) [2]
Это уже миллионный поток для рассылки спамерских писем.
——————
SPAMERS MUST DIE.
← →
Матлабист
(2004-04-28 16:35)
[4]
> Что означает этот эррор и как его лечить?
Код приведи что-ль…
← →
csr ©
(2004-04-28 17:29)
[5]
Я использую класс TThread, по этому чвно не указываю размер стека… И в кол-ве потоков тут не проблема, т.к. подобные штуки и на большем кол-ве потоков работали… А тут… буквально 1500 потоков всего и такая вот ерунда получается… Не может поток даже стартануть. А если ставим скажем 1000 потоков, то пашет все ок… Может можно как-нить разобраться в чем дело?
2 Матлабист : Ты хочешь чтоб я тут привел код модуля потока?? ))
← →
Тимохов ©
(2004-04-28 17:31)
[6]
а на фига столько?
1) спам
2) жизнь моделируете
← →
csr ©
(2004-04-28 17:46)
[7]
2 Тимохов:
А какая разница? Мне поставили задачу — я пишу прогу, выполняю, то что мне сказали — мое дело малое… Сказали так сделать, вот и делааю…
Вы мне лучше подскажите конкретно по сабжу, пожалйста.
← →
Игорь Шевченко ©
(2004-04-28 17:50)
[8]
> А тут… буквально 1500 потоков всего и такая вот ерунда
> получается
Дурацкое решение. Все процессорное время будет тратиться на переключение контекстов.
← →
Smithson ©
(2004-04-28 17:51)
[9]
Конкретно по сабжу, на выбор:
1. Уменьшить число потоков
2. Уменьшить потребности каждого экземпляра потока в ресурсах (стек, память в куче, объекты системы)
3. Привести код (с комментариями), тогда возможно будет его проанализировать (если найдутся желающие) и подсказать пути оптимизации или решения этой же задачи другими средствами.
4. Ну или сидеть и думать самому.
Выбирай.
← →
csr ©
(2004-04-28 17:52)
[10]
2 Игорь Шевченко
более умное решение можешь предложить? Проц атлон 3000 загружает на 30% максимум! Тут не в этом вопрос! Все написано ОК, но почему-то ошибка вылетает! Кто знает как пофиксить это??
← →
csr ©
(2004-04-28 17:55)
[11]
2 Smithson ©
Вариант №2: Подскажи, как используя класс TThread Уменьшить потребности каждого экземпляра потока в ресурсах (стек, память в куче, объекты системы) ?
← →
Smithson ©
(2004-04-28 17:58)
[12]
Это класс довольно экономно расходует реcурсы. Но ты-то используешь не TThread, а его потомка, про таланты и аппетиты которого нам по-прежнему ничего не известно.
← →
csr ©
(2004-04-28 18:01)
[13]
2 Smithson ©
А уменьшить кол-во потоков — низя… Мне б наоборот достичь того чтоб увеличить их мона было
И вот еще что: если в пределах одного процесса стартануть еще 1000 потоков (но уже другого назначения), то тож такой баг… А если несколько копий проги запустить, то все на 1000 потоках валят как надо )) Только правда проц умирает почти полностью…
← →
csr ©
(2004-04-28 18:04)
[14]
2 Smithson ©
Дак создается он по дефолту — никаких значений размера стека и прочего я не менял…
Как это можнго сделать?
← →
Игорь Шевченко ©
(2004-04-28 18:06)
[15]
> Мне б наоборот достичь того чтоб увеличить их мона было
>
Можно вопрос ? Что за задача такая ?
← →
Тимохов ©
(2004-04-28 18:07)
[16]
> Игорь Шевченко © (28.04.04 18:06) [15]
вам же сказал — какая вам разница
← →
Smithson ©
(2004-04-28 18:12)
[17]
Да, я видимо не точно сформулировал свои пункты. По 1, 2 и 4 пункту возможно только самостоятельная работа. И только 3 пункт может стать основой для продолжения обсуждения.
Удачи!
← →
csr ©
(2004-04-28 18:36)
[18]
2 Smithson ©
Дак ты не знаешь как менять размер стека у потомков класса TThread ?
← →
Тимохов ©
(2004-04-28 18:44)
[19]
в потомке tthread перекрыть конструктор (см. tthread.create)
в BeginThread вторым парметром передавать не 0, а другое значение.
почитать в MSDN про функцию createthread — я точно не помню — достаточно ли этого будет или нужно еще уменьшить размер стека у всего приложения.
← →
Smithson ©
(2004-04-28 18:57)
[20]
constructor TThread.Create(CreateSuspended: Boolean);
var
Flags: DWORD;
begin
inherited Create;
AddThread;
FSuspended := CreateSuspended;
Flags := 0;
if CreateSuspended then Flags := CREATE_SUSPENDED;
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), Flags, FThreadID);
end;
0 — означает, что система сама оперирует стеком и выделяет столько, сколько нужно. Отсюда вывод — ты в своем потомке этого класса не жри так стек и он будет расходоваться экономнее.
← →
Тимохов ©
(2004-04-28 18:59)
[21]
> 0 — означает, что система сама оперирует стеком и выделяет
> столько, сколько нужно
нет
размер берется из основной программы.
← →
Тимохов ©
(2004-04-28 19:00)
[22]
чтобы быть корректным в терминах поправлю себя — из главного потока, а не из основной программы.
← →
panov ©
(2004-04-28 19:02)
[23]
>Игорь Шевченко © (28.04.04 18:06) [15]
Дык вот ответ — http://www.caesar-soft.biz/
← →
Smithson ©
(2004-04-28 19:03)
[24]
Ос, не знал. Считал, что система сама распределяет по страничке…
Спасибо.
← →
Игорь Шевченко ©
(2004-04-28 19:09)
[25]
[23] panov © (28.04.04 19:02)
SPAMERS MUST DIE!!!
И как у людей совести хватает…
← →
csr ©
(2004-04-28 21:16)
[26]
2 panov ©
Ну что ты сайт-то светишь? Я щас не работаю там. Чего ты тут шорох наводишь? Не можешь ответить — вот и не отвечай.
Спасибо господа, я попробую с размером стека… Позже сообщу что получилось…
← →
Игорь Шевченко ©
(2004-04-28 22:33)
[27]
csr © (28.04.04 21:16)
> Ну что ты сайт-то светишь?
Так ты его сам в анкете светишь. Нафиг спамеров, давить их, как тараканов. Тем более, многопоточных.
← →
Юрий Зотов ©
(2004-04-28 23:44)
[28]
Многопоточный таракан?
М-м-м… оригинально…
Очень хочется, чтобы игры с размером стека не прошли. Задолбали вы своим мусором, ребята. Так что вините себя же… творцы спамерских тулзов… блин.
← →
Digitman ©
(2004-04-29 08:32)
[29]
хуже спамера только спамер-дилетант с инициативой)
безо всяких доп.потоков вполне можно обойтись для решения той же гнилой задачи)
← →
Smithson ©
(2004-04-29 10:46)
[30]
Тимохов © (28.04.04 19:00) [22]
Для общего развития можно уточнения? Из главного (первого) потока прорцесса или из вызывающего потока? Ведь BeginThread может дернуть и вторичный поток…
← →
Тимохов ©
(2004-04-29 11:25)
[31]
> Smithson © (29.04.04 10:46) [30]
В доке написано, что если передавать 0, то будет браться размер стека главного потока.
Сами посмотрите createthread+f1.
Всем.
Вот блин — в анкету забыл посмотреть и совет дал, хорошо бы чтобы не правильный :(((
← →
Smithson ©
(2004-04-29 11:28)
[32]
Спасибо, пошел в MSDN. Не люблю я его…
← →
Тимохов ©
(2004-04-29 11:30)
[33]
> Smithson © (29.04.04 11:28) [32]
Можно в дельфи почитать
вот
dwStackSize
Specifies the size, in bytes, of the stack for the new thread. If 0 is specified, the stack size defaults to the same size as that of the primary thread of the process.
← →
csr ©
(2004-04-29 12:26)
[34]
Спасибо за понимание господа)) А неподскажите-ли также любезно, от чего может происходить ошибка Thread creation error: Not enough storage is available to process this command?
← →
Игорь Шевченко ©
(2004-04-29 12:35)
[35]
csr © (29.04.04 12:26)
Не подскажем.
Spamers must die.
← →
Григорьев Антон
(2004-04-29 12:39)
[36]
> csr © (29.04.04 12:26) [34]
> Спасибо за понимание господа))
Какое, к чёрту, понимание? Нормальный человек никогда не поймёт тех [вырезано цензурой], которые зарабатывают деньги тем, что портят жизнь другим людям.
← →
Юрий Зотов ©
(2004-04-29 12:55)
[37]
> csr © (29.04.04 12:26) [34]
> от чего может происходить ошибка Thread creation error: Not
> enough storage is available to process this command?
Я думаю, Вам стоит написать письмо с этим вопросом в известный Центр американского английского. Нет сомнений, что тамошние специалисты смогут совершенно точно перевести эту фразу и дать квалифицированный ответ. Причем неоднократно. Чтобы лучше дошло.
← →
Digitman ©
(2004-04-29 13:06)
[38]
> csr © (29.04.04 12:26) [34]
> от чего может происходить ошибка Thread creation error:
> Not enough storage is available to process this command?
в при всем неприятии тебя как LMD и SMD тебе теме не менее уже разжевали — ты как минимум стеками своих потоков «сожрал» ВСЕ доступное ВАП процесса)).. не говоря уже о прикладной «спаммерской» логики самих потоков))
p.s.
«Боня, ты тупой !» (с) КВН
← →
Тимохов ©
(2004-04-29 13:25)
[39]
> «Боня, ты тупой !» (с) КВН
а куда же им деваться, только в спамеры подаваться.
«От Ивана.
Супир нодддежжные маас совые росссылке 10000000000 адрисссов всиго за 100 уё»
← →
csr ©
(2004-04-30 14:35)
[40]
Удалено модератором
Примечание: Offtopic
I localized problem of my Delphi service app.
Now I have one test server with Windows Server 2019, RDP.
Simple test code, connecting to local TCP server and disconnect:
for i := 1 to 1000000 div 100 do
begin
sleep(100);
Caption := 'STRESS TEST: ' + inttostr(i * 100);
Application.ProcessMessages;
for j := 1 to 100 do
begin
thread := TThread.CreateAnonymousThread(
procedure
Var tcpClient : TIdTcpClient;
begin
try
tcpClient := TIdTCPClient.Create(nil);
tcpClient.Host := '127.0.0.1';
tcpClient.Port := RollControl_Svc.TCPServer.Bindings[0].Port
tcpClient.Connect;
tcpClient.IOHandler.ReadTimeout := 1000;
finally
FreeAndNil(tcpClient);
end;
end);
thread.FreeOnTerminate := (j > 1) and (j < 100);
if thread.FreeOnTerminate then thread.Start else
begin
thread.Start;
thread.WaitFor;
thread.Free;
end;
end;
After 20K operations on the test machine, an error occurs:
Thread creation error: Not enough memory resources are available to process this command.
At my work with the machine everything is fine, 1M operations have been done. I have Delphi XE3, latest Indy version, what’s wrong? Maybe there are some peculiarities when working in RDP?
asked Jul 23, 2021 at 14:14
5
This issue is not specific to Indy. The code shown has the potential of running thousands of threads simultaneously, each one taking up a kernel object, using a default stack size of 1-4MB, etc. Add that up, and that is a LOT of memory and system resources potentially being used. So, it makes sense that as the loop progresses, new threads could fail with ERROR_NOT_ENOUGH_MEMORY
over time.
One option to mitigate this is to reduce the stack size of each thread, since this code is doing very little work in each thread, so doesn’t need a large stack. TThread
did not offer this option on a per-thread basis until Delphi 10.3 Rio, but the Win32 API has always supported it (see How to set stack size in TThread?). Or, you can set the default stack size globally in the project setting for the whole app, or in code via {$MINSTACKSIZE}
.
Another option is to reduce the number of threads that are running simultaneously. Such as by using a queue of tasks run by a thread pool that limits the number of running tasks.
answered Jul 23, 2021 at 15:36
Remy LebeauRemy Lebeau
536k30 gold badges444 silver badges750 bronze badges
Yes, it was no Indy
Next code:
no := 0;
List := TList.Create;
while true do
begin
Caption := 'STRESS TEST: ' + inttostr(no);
Application.ProcessMessages;
List.Clear;
for j := 1 to 1000 do
begin
inc(no);
Thread := TThread.CreateAnonymousThread(
procedure
begin
end
);
thread.FreeOnTerminate := false;
thread.Start;
List.Add(thread)
end;
while List.Count > 0 do
begin
TThread(List[0]).WaitFor;
TThread(List[0]).Free;
List.Delete(0);
end;
end;
After 400K operations, an error occurs on the test machine. I didn’t understand why. Clean code, all threads are created and destroyed in a loop. Local test passes 10 million operations, test PC only 400K and fails
answered Jul 23, 2021 at 18:47
1
Cannot reproduce this because the host is on a local network i assume. this is likely down to the amount of ram you have installed. If it’s graphically intensive it could also be down to vram(graphics card memory). Best thing to do is to replicate the code but for a normal basic website and if it works you know its a ram/vram problem
answered Jul 23, 2021 at 14:55
0
Мастера подскажите, как бороться с “thread creation error: Недостаточно памяти для обработки команды”, говорит, что, мол, мало памяти, хотя под стек выделено 256M {$M 16384,268435456}, на машине стоит 512М, в диспетчере задач приложение показывает, что для приложения выделено около 5M. Пишу на Delphi 7 под WinXP.
Может, кто сталкивался с такой бедой, из каких соображений принимается решение, что не хватает памяти. До того как в проге было мало элементов (меньше сотни кнопок, меток и т.д.) такое сообщение не выскакивало, сейчас их несколько сотен, такое сообщение выскакивает, после того, как вызываю play_sound для проигрывания wav файла, но ф-н sndPlaySound все время выдает FALSE, хотя перенес этот модуль из старого проекта там все работало, а после этого еще раз play_sound но для пробирования тона, процесс (Thread) созданный sndPlaySound так и остается, а звука нет. Причем если вызывать sndPlaySound с тем же именем файла, но указанным как константа – звук есть, если же переменная (PChar) – звука нет.
Содержание ComboBox’ов (ItemIndex = -1 если задал имя файла ):
нет
100 Гц, 1 гудок
100 Гц, 2 гудка
200 Гц, 1 гудок
200 Гц, 2 гудка
300 Гц, 1 гудок
300 Гц, 2 гудка
500 Гц, 1 гудок
500 Гц, 2 гудка
700 Гц, 1 гудок
700 Гц, 2 гудка
1000 Гц, 1 гудок
1000 Гц, 2 гудка
1500 Гц, 1 гудок
1500 Гц, 2 гудка
2000 Гц, 1 гудок
2000 Гц, 2 гудка
type
TPlayToneThread = class(TThread) // Поток проигрывания тона
private
Frequency: integer; // Частота тона, Гц
Duration: integer; // Длительность выдачи тона, мс
Count: integer; // Кол-во выдаваемых тонов
protected
procedure Execute; override; // Исполняемая часть
end;
//———————————— Выдать на динамик тон —————————————-
procedure Sound(Frequency, Duration: Integer);
asm
push edx
push eax
mov eax, Win32Platform
cmp eax, VER_PLATFORM_WIN32_NT
jne @@9X
call Windows.Beep
ret
@@9X:
pop eax
pop edx
push ebx
push edx
mov bx, ax
mov ax, 34DDh
mov dx, 0012h
cmp dx, bx
jnc @@2
div bx
mov bx, ax
in al, 61h
test al, 3
jnz @@1
or al, 3
out 61h, al
mov al, 0B6h
out 43h, al
@@1:
mov al, bl
out 42h, al
mov al, bh
out 42h, al
call Windows.Sleep
in al, 61h
and al, 0FCh
out 61h, al
jmp @@3
@@2:
pop edx
@@3:
pop ebx
end;
//——————————— Реализация потока проигрывания тона —————————-
procedure TPlayToneThread.Execute;
begin
FreeOnTerminate:=True; // По завершению работы освободить память
while Count>0 do
begin
Sound(Frequency,Duration);
sleep(Duration);
dec(Count);
end;
Terminate; // На всяк случай завершаем поток
end;
//——————————— Процедура завершения потока ————————————
procedure TfmOSC_Buzzer.end_thread(Sender: TObject);
begin
PlayToneThread:=nil; // На всяк случай уничтожаем объект
end;
//————————————— Проиграть звук ———————————————
procedure TfmOSC_Buzzer.play_sound(cbSound: TComboBox; play: boolean = false);
const
Duration: integer = 75;
var
Frequency, Count: integer;
begin
if cbSound.ItemIndex=0 then exit; // Если нечего проигрывать то выходим
if cbSound.ItemIndex<0 then // Если это *.wav файл
try
sndPlaySound(PChar(cbSound.Text),SND_ASYNC); // то просто проигрываем его
except
end
else begin
Frequency:=StrToInt(Trim(Copy(cbSound.Text,1,4))); // Определили частоту и кол-во гудков
if Odd(cbSound.ItemIndex) then Count:=1 else Count:=2;
if IsWindowsNT then
begin
{
if PlayToneThread<>nil then // Если поток существует
if not PlayToneThread.Terminated then // Да он еще и не завершен
begin
if play then // Если нужно проиграть
PlayToneThread.Terminate // то завершили поток
else // Если событие
exit; // то выходим
end;
PlayToneThread:=TPlayToneThread.Create(true); // Создаем поток
PlayToneThread.OnTerminate:=end_thread; // Задали процедуру завершения
PlayToneThread.Priority:=tpNormal; // Задаем нормальный приоритет потоку
PlayToneThread.Frequency:=Frequency;
PlayToneThread.Duration:=Duration;
PlayToneThread.Count:=Count;
PlayToneThread.Resume; // Запускаем поток
}
{}
while Count>0 do
begin
Sound(Frequency,Duration);
sleep(Duration);
dec(Count);
end;
{}
end
else begin
while Count>0 do
begin
Sound(Frequency,Duration);
sleep(Duration);
dec(Count);
end;
end;
end;
end;
vuasya 1 / 1 / 2 Регистрация: 26.08.2013 Сообщений: 381 |
||||
1 |
||||
Правильно вызвать поток24.03.2014, 00:51. Показов 2390. Ответов 2 Метки нет (Все метки)
Вызываю поток следующим образом
но дает ошибку : thread creation error недостаточно памяти для обработки команды … как мне от нее избавиться ? чтоб не выдавало у меня ее ? как я понял ошибка вылетает в результате функции repeat- until , но если их убрать , то поток не закончит дело до конца (а именно гет запрос по ссылкам) подскажите, как быть ?
__________________
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
24.03.2014, 00:51 |
2 |
2649 / 2270 / 279 Регистрация: 24.12.2010 Сообщений: 13,725 |
|
24.03.2014, 10:28 |
2 |
недостаточно памяти для обработки команды Ты ж этих потоков наплодил туеву хучу одновременно, а ведь каждый из них требует минимум 1 Мб вирт.памяти в пространстве процесса ! А оно не резиновое, пространство это. — для размещения пользовательских данных, кода и стеков процессу Win32-система может выделить не более 2 Гб Вот и считай сколько объектов-потоков можно теоретически создать одновременно)
0 |
vuasya 1 / 1 / 2 Регистрация: 26.08.2013 Сообщений: 381 |
||||
24.03.2014, 15:47 [ТС] |
3 |
|||
понимаю, а как можно тогда переделать ? мне тут подсказали об TThreadList , но вот никак не могу с ним разобраться … надо проверять кол-во работающих потоков и если их мало , то создавать новый поток и дописывать его в список, хранящий работающие потоки.
, но код не пашет , зависает …
0 |
thread creation error insufficient memor
, Как бороться с “thread creation error: Мало памяти
|
|
Мастера подскажите, как бороться с “thread creation error: Недостаточно памяти для обработки команды”, говорит, что, мол, мало памяти, хотя под стек выделено 256M {$M 16384,268435456}, на машине стоит 512М, в диспетчере задач приложение показывает, что для приложения выделено около 5M. Пишу на Delphi 7 под WinXP. Содержание ComboBox’ов (ItemIndex = -1 если задал имя файла ): type TPlayToneThread = class(TThread) // Поток проигрывания тона private Frequency: integer; // Частота тона, Гц Duration: integer; // Длительность выдачи тона, мс Count: integer; // Кол-во выдаваемых тонов protected procedure Execute; override; // Исполняемая часть end; //———————————— Выдать на динамик тон —————————————- procedure Sound(Frequency, Duration: Integer); asm push edx push eax mov eax, Win32Platform cmp eax, VER_PLATFORM_WIN32_NT jne @@9X call Windows.Beep ret @@9X: pop eax pop edx push ebx push edx mov bx, ax mov ax, 34DDh mov dx, 0012h cmp dx, bx jnc @@2 div bx mov bx, ax in al, 61h test al, 3 jnz @@1 or al, 3 out 61h, al mov al, 0B6h out 43h, al @@1: mov al, bl out 42h, al mov al, bh out 42h, al call Windows.Sleep in al, 61h and al, 0FCh out 61h, al jmp @@3 @@2: pop edx @@3: pop ebx end; //——————————— Реализация потока проигрывания тона —————————- procedure TPlayToneThread.Execute; begin FreeOnTerminate:=True; // По завершению работы освободить память while Count>0 do begin Sound(Frequency,Duration); sleep(Duration); dec(Count); end; Terminate; // На всяк случай завершаем поток end; //——————————— Процедура завершения потока ———————————— procedure TfmOSC_Buzzer.end_thread(Sender: TObject); begin PlayToneThread:=nil; // На всяк случай уничтожаем объект end; //————————————— Проиграть звук ——————————————— procedure TfmOSC_Buzzer.play_sound(cbSound: TComboBox; play: boolean = false); const Duration: integer = 75; var Frequency, Count: integer; begin if cbSound.ItemIndex=0 then exit; // Если нечего проигрывать то выходим if cbSound.ItemIndex<0 then // Если это *.wav файл try sndPlaySound(PChar(cbSound.Text),SND_ASYNC); // то просто проигрываем его except end else begin Frequency:=StrToInt(Trim(Copy(cbSound.Text,1,4))); // Определили частоту и кол-во гудков if Odd(cbSound.ItemIndex) then Count:=1 else Count:=2; if IsWindowsNT then begin { if PlayToneThread<>nil then // Если поток существует if not PlayToneThread.Terminated then // Да он еще и не завершен begin if play then // Если нужно проиграть PlayToneThread.Terminate // то завершили поток else // Если событие exit; // то выходим end; PlayToneThread:=TPlayToneThread.Create(true); // Создаем поток PlayToneThread.OnTerminate:=end_thread; // Задали процедуру завершения PlayToneThread.Priority:=tpNormal; // Задаем нормальный приоритет потоку PlayToneThread.Frequency:=Frequency; PlayToneThread.Duration:=Duration; PlayToneThread.Count:=Count; PlayToneThread.Resume; // Запускаем поток } {} while Count>0 do begin Sound(Frequency,Duration); sleep(Duration); dec(Count); end; {} end else begin while Count>0 do begin Sound(Frequency,Duration); sleep(Duration); dec(Count); end; end; end; end; Сообщение отредактировано: Song — 17.01.05, 05:21 |
s-mike |
|
Надо же код выделять тегами. Что в правилах написано? Цитата Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля. Добавлено 16.01.05, 18:30 |
Anatoly Podgoretsky |
|
Говоришь под ХР, а как тогда понимать обращение к регистрам? |
msn777 |
|
>Говоришь под ХР, а как тогда понимать обращение к регистрам? >Говоришь под ХР, >а как тогда понимать обращение к регистрам? |
Topic: [SOLVED] Thread creation problems (Read 2833 times)
Hi there everyone,
I’m working on rewriting an application I wrote a while ago.
{ TParentThread }
TParentThread = class(TThread)
private
{ private decelarations }
// a critical section
FCriticalSection: TCriticalSection;
protected
{ protected decelarations }
procedure Execute; override;
public
{ public decelarations }
// the TCP client
FTCPClient: TIdTCPClient;
// constructor and destructor
constructor Create(ATCPClient: TIdTCPClient);
destructor Destroy; override;
// enter critical section
procedure Lock;
// leave critical section
procedure Unlock;
end;
constructor TParentThread.Create(ATCPClient: TIdTCPClient);
begin
// set reference to the TCP client
FTCPClient := ATCPClient;
// create a critical section instance
FCriticalSection := TCriticalSection.Create;
inherited Create(True);
end;
{ TThreadVilles }
TThreadVilles = class(TParentThread)
private
{ private declarations }
FOnVille: TFillComboBoxEx;
procedure DoFillComboBoxEx;
protected
{ protected declarations }
procedure Execute; override;
public
{ public declarations }
// constructor and destructor
constructor Create(ATCPClient: TIdTCPClient);
destructor Destroy; override;
// property
property OnVille: TFillComboBoxEx read FOnVille write FOnVille;
end;
constructor TThreadVilles.Create(ATCPClient: TIdTCPClient);
begin
inherited;
Create(ATCPClient);
end;
procedure TfrmVilles.FormShow(Sender: TObject);
begin
// Create the thread
DataThread := TThreadVilles.Create(FTCPClient); <-- The error occurs here
//
DataThread.Start;
//
DataThread.DoFillComboboxEx;
end;
The code above is part of the program & I keep getting an error on the line where the thread is created which says Thread creation error: insufficient space to treat this command. See attachment. I’ve never had such a problem before. The message is rather confusing because I have 4GB of RAM.
I would appreciate the insight of the community about how to get round this problem.
Thanks,
JD
« Last Edit: March 31, 2015, 05:28:00 pm by JD »
Logged
Windows (10) — Lazarus 2.1/FPC 3.2 (svn 64160 built using fpcupdeluxe),
Linux Mint — Lazarus 2.1/FPC 3.2 (svn 64380 built using fpcupdeluxe),
Delphi
Indy 10.6 series; mORMot; Zeos 7.3; SQLite, Firebird, PostgreSQL & MariaDB; VirtualTreeView 5.5.3 R1
I assume you have a typo. Change:
constructor TThreadVilles.Create(ATCPClient: TIdTCPClient);
begin
inherited;
Create(ATCPClient);
end;
to:
constructor TThreadVilles.Create(ATCPClient: TIdTCPClient);
begin
inherited Create(ATCPClient);
end;
Logged
@engkin Thanks a lot. I completely missed that!
Logged
Windows (10) — Lazarus 2.1/FPC 3.2 (svn 64160 built using fpcupdeluxe),
Linux Mint — Lazarus 2.1/FPC 3.2 (svn 64380 built using fpcupdeluxe),
Delphi
Indy 10.6 series; mORMot; Zeos 7.3; SQLite, Firebird, PostgreSQL & MariaDB; VirtualTreeView 5.5.3 R1