Thread creation error: Not enough memory resources are available to process this command.are you trying 32-bit or 64-bit? something to read (https://devblogs.microsoft.com/oldnewthing/20050729-14/?p=34773)
Thread creation error: Not enough memory resources are available to process this command.are you trying 32-bit or 64-bit? something to read (https://devblogs.microsoft.com/oldnewthing/20050729-14/?p=34773)
Thread creation error: Not enough memory resources are available to process this command.
Can you please provide us with the RAM amount for both the test machine and the client machine?
I tested the code on different computers, somewhere it works, somewhere it doesn't. There are enough system resources, 100 threads are 1GB of system memory, there is enough of this everywhere.
I tested the code on different computers, somewhere it works, somewhere it doesn't.and that is normal. the address space layout will not be identical in all versions of Windows even for the same program. ASLR alone is going to make them vary not to mention the configuration of the Windows installation.
There are enough system resources, 100 threads are 1GB of system memory, there is enough of this everywhere.It isn't just about how much memory is available. Memory isn't the only resource consumed by threads.
So 500 threads are 5GB of memory. So how much memory can a 32-bit app use (depending on windows edition and tuning, 2,3 or 4 GB, but certainly not more)
The really important question is, do you really need hundreds of threads to solve the problem (whatever it may be) ? if you do, a PC class machine isn't the ideal machine to solve the problem (understatement of the day.)
I was wrong. 1 Thread is 1MB, 100 is 100MB, 1000 is 1GBWhy would 1 thread be equal to 1Mb?
This test is the localization of the problem...Why would you suspect the number of threads then? If the number of threads used in the app are "normal"?
The multithreading app stops working after a certain amount of time, may be 1 day, may be week. App connecting to database and making queries by requests of hardware stations. No heavy load, normal number of threads, randomly crashed on several pc
I still can't figure out why the error occurs on some PC. In my case, threads are created and destroyed, there can be no more than 500 threads at the same time. Everything works for me locally without failures, on the test machine after a while the error of creating new threads starts to appearIt is possible that your experiencing the different context-switching time.
test 1000 1
(spawning 1000 threads with 1Mb stack size) all of them should be created.Why would 1 thread be equal to 1Mb?
I thought the default stack size of a thread is 4Mb.
The default size is whatever the program's PE header specifies, which can be set via the {$MINSTACKSIZE} (https://www.freepascal.org/docs-html/3.0.0/prog/progsu104.html) and {$MAXSTACKSIZE} (https://www.freepascal.org/docs-html/3.0.0/prog/progsu102.html#x110-1110001.3.19) directives.The setting only applies to the main thread (as the thread is launched by the system).
The setting only applies to the main thread (as the thread is launched by the system).
The stack size of a thread launched by the application is defined in run-time.
WinAPI CreateThread (https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread) has dwStackSize parameter.
dwStackSize
The initial size of the stack, in bytes. The system rounds this value to the nearest page. If this parameter is zero, the new thread uses the default size for the executable. For more information, see Thread Stack Size (https://docs.microsoft.com/en-us/windows/desktop/ProcThread/thread-stack-size).
The default size for the reserved and initially committed stack memory is specified in the executable file header. Thread or fiber creation fails if there is not enough memory to reserve or commit the number of bytes requested. The default stack reservation size used by the linker is 1 MB. To specify a different default stack reservation size for all threads and fibers, use the STACKSIZE statement in the module definition (.def) file. The operating system rounds up the specified size to the nearest multiple of the system's allocation granularity (typically 64 KB). To retrieve the allocation granularity of the current system, use the GetSystemInfo function.
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. Generally, the reserve size is the default reserve size specified in the executable header. However, if the initially committed size specified by dwStackSize is larger than or equal to the default reserve size, the reserve size is this new commit size rounded up to the nearest multiple of 1 MB.
To change the reserved stack size, set the dwCreationFlags parameter of CreateThread or CreateRemoteThread to STACK_SIZE_PARAM_IS_A_RESERVATION and use the dwStackSize parameter. In this case, the initially committed size is the default size specified in the executable header. For fibers, use the dwStackReserveSize parameter of CreateFiberEx. The committed size is specified in the dwStackCommitSize parameter.
FPC TThread.Create (https://www.freepascal.org/docs-html/rtl/classes/tthread.create.html) has a parameter to the stack size which is defaulted to DefaultStackSize.
The value of DefaultStackSize doesn't depends on {$MAXSTACKSIZE}
The setting applies as the default for ANY thread where a stack size is not specified explicitly.TThread always specifies it explicitly (from WinAPI prespective).
...
It CAN be specified at runtime, but if it is NOT specified then the default specified in the PE header is used instead.
... On the other hand, nothing stops a user from creating a TThread object with StackSize=0 to use the default from the PE header
TThread always specifies it explicitly (from WinAPI prespective).
Unless the code using TThread explicitly specifies NOT to use it (by passing stack size as zero).