Hi
Yup, it's /expensive/ to start a thread ~ 1-2 msecs, depending on how old your gear is...
It's expensive but not _that_ expensive.
On a dual core VM running at 2.8Ghz with 5GB of memory it takes an _average_ of 60 secs to create and end 100,000 threads. That means Windows is creating 1,666 threads per second but, this is not a fair measurement, that average is quite a bit worse than the time it takes to create a dozen threads (the typical case), because thread creation and termination occur asynchronously which means that when 100,000 threads are created in a tight loop (with the goal of measuring average elapsed time to create a single thread), the system ends up having to manage _thousands_ of threads that have not ended yet and, those thread consume large amounts of memory (stack allocations.) Also, to keep the system running reasonable well, it is necessary to call CloseHandle and ExitThread for each thread (which consume time not spent creating threads.)
Bottom line, the test indicates that Windows is creating an average of 1,666 threads per second but, in normal circumstances (creating about 16 threads), it is extremely likely that the average is several times that number.
For the curious out there, here is the code used to test CreateThread:
{$APPTYPE CONSOLE}
program _CreateThreadElapsedTime;
uses
Windows
;
function EmptyThread(Parameter : pointer) : DWORD; stdcall;
begin
ExitThread(0);
end;
var
ThreadHandle : THANDLE;
ThreadId : DWORD;
i : int32;
const
LOOP_COUNT = 100000;
begin
i := 0;
while i < LOOP_COUNT do
begin
ThreadHandle := CreateThread(nil,
0,
@EmptyThread,
nil,
0,
ThreadId);
if ThreadHandle = 0 then
begin
writeln('CreateThread failed. Loop terminated at ', i);
break;
end;
CloseHandle(ThreadHandle);
inc(i);
end;
if ThreadHandle = 0 then
begin
{ if CreateThread failed wait for a carriage return }
readln;
end;
end.
PS: only tested 64 bit version of the code (32 bit would take longer.)
ETA:The lack of timing instructions is because my command line interpreter can measure the elapsed time between process creation and termination. Since the CLI does it, I don't need to add code to measure elapsed time.