Модератор: Модераторы
hinst писал(а):@VKB: я оказывается немного не то проверял.
Если создавать поток функцией Windows.CreateThread и передать размер стека 0, то он выделит 16 мегабайт. То есть, можно считать, что 16 мегабайт это размер стека для потока, который выделяет операционная система по умолчанию
dwStackSize [in]
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.
wavebvg писал(а):...
2. Один факт того, что при завершении потока стоит Sleep в 100мс дает понять всю серьёзность проблемы
hinst писал(а):Что-то я не найду, где там Sleep(100)
Вот сейчас специально смотрел и не нашёл
sleep(100)
{$mode objfpc}
uses cthreads,sysutils,dateutils;
const MaxThreads=300;
function increment(parameter: pointer):PtrInt;
begin result:=0; end;
var ths:array [1..MaxThreads] of TThreadID;
dt:tdatetime; i:ptruint;
begin
dt:=now();
for i:=1 to MaxThreads do ths[i]:=BeginThread(@increment,pointer(i));
for i:=1 to MaxThreads do WaitForThreadTerminate(ths[i],0);
writeln('Общее время работы: ',millisecondsbetween(now(),dt));
end.
function TThread.WaitFor: Integer;
begin
WRITE_DEBUG('waiting for thread ',ptruint(FHandle));
If (MainThreadID=GetCurrentThreadID) then
{
FFinished is set after DoTerminate, which does a synchronize of OnTerminate,
so make sure synchronize works (or indeed any other synchronize that may be
in progress)
}
While not FFinished do
CheckSynchronize(100);
WaitFor := WaitForThreadTerminate(FHandle, 0);
{ should actually check for errors in WaitForThreadTerminate, but no }
{ error api is defined for that function }
FThreadReaped:=true;
WRITE_DEBUG('thread terminated');
end;
{$mode objfpc}
uses cthreads,sysutils,dateutils,classes;
const MaxThreads=300;
type
{ TMyThread }
TMyThread = class(TThread)
private
FTime: Integer;
protected
procedure Execute; override;
procedure SyncOnTerminated(Sender: TObject);
public
constructor Create(CreateSuspended: Boolean; const StackSize: SizeUInt = DefaultStackSize);
property Time: Integer read FTime write FTime;
end;
function increment(parameter: pointer):PtrInt;
begin Sleep(Integer(parameter)); end;
var ths:array [1..MaxThreads] of TThreadID;
dt:tdatetime; i:ptruint;
var ths1:array [1..MaxThreads] of TMyThread;
{ TMyThread }
procedure TMyThread.Execute;
begin
Sleep(Time);
end;
procedure TMyThread.SyncOnTerminated(Sender: TObject);
begin
end;
constructor TMyThread.Create(CreateSuspended: Boolean; const StackSize: SizeUInt);
begin
inherited;
end;
begin
dt:=now();
for i:=1 to MaxThreads do ths[i]:=BeginThread(@increment,pointer(i*10));
for i:=1 to MaxThreads do WaitForThreadTerminate(ths[i],0);
writeln('Общее время работы: ',millisecondsbetween(now(),dt));
for i:=1 to MaxThreads do
begin
ths1[i]:=TMyThread.Create(true);
ths1[i].Time:=i*10;
ths1[i].OnTerminate := @ths1[i].SyncOnTerminated;
end;
dt:=now();
for i:=1 to MaxThreads do ths1[i].Resume;
for i:=1 to MaxThreads do ths1[i].WaitFor;
writeln('Общее время работы: ',millisecondsbetween(now(),dt));
for i:=1 to MaxThreads do ths1[i].Free;
end.
Общее время работы: 3012
Общее время работы: 3101
xdsl писал(а):Что касается Вашего второго примера, то Вы там сами делаете Sleep, в исполняемых методах. Естественно, что нити не завершат работу, пока не закончат каждая свой Sleep. Уберите его, и получите время работы от 10 до 200 мс на каждый набор из 300 потоков.
While not FFinished do
CheckSynchronize(100);
Delphi, кстати, передаёт 0 в BeginThread в качестве размера стека, что интерпретируется как "такой же размер стека, как и для основного потока".
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 24