TThreadを使用して、ファイルサイズを小さく保つことができます。あなたは困難な道を進んでいると思います。車輪の再発明には時間がかかります。:)
スレッドを初期化するための実用的なコードは次のとおりです。
function ThreadProc(Thread: TThread): Integer;
var FreeThread: Boolean;
begin
if not Thread.FTerminated then
try
result := 0; // default ExitCode
try
Thread.Execute;
except
on Exception do
result := -1;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Thread.FFinished := True;
if Assigned(Thread.OnTerminate) then
Thread.OnTerminate(Thread);
if FreeThread then
Thread.Free;
EndThread(result);
end;
end;
constructor TThread.Create(CreateSuspended: Boolean);
begin
IsMultiThread := true; // for FastMM4 locking, e.g.
inherited Create;
FSuspended := CreateSuspended;
FCreateSuspended := CreateSuspended;
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
if FHandle = 0 then
raise Exception.Create(SysErrorMessage(GetLastError));
SetThreadPriority(FHandle, THREAD_PRIORITY_NORMAL);
end;
つまりpointer()
、スレッド作成APIに関してオブジェクトを渡します。これは、ThreadProcの一意のパラメーターとして渡されます。
ThreadProcはメソッドの一部ではなく、ユニットに対してグローバルである必要があります。
APIを直接呼び出して、オーバーヘッドなしでマルチスレッド圧縮と同期を処理する別のコードを次に示します。
type
TThreadParams = record
bIn, bOut: pAESBlock;
BlockCount: integer;
Encrypt: boolean;
ID: DWORD;
AES: TAES;
end;
{ we use direct Windows threads, since we don't need any exception handling
nor memory usage inside the Thread handler
-> avoid classes.TThread and system.BeginThread() use
-> application is still "officialy" mono-threaded (i.e. IsMultiThread=false),
for faster System.pas and FastMM4 (no locking)
-> code is even shorter then original one using TThread }
function ThreadWrapper(var P: TThreadParams): Integer; stdcall;
begin
with P do
AES.DoBlocks(bIn,bOut,bIn,bOut,BlockCount,Encrypt);
ExitThread(0);
result := 0; // make the compiler happy, but won't never be called
end;
procedure TAES.DoBlocksThread(var bIn, bOut: PAESBlock; Count: integer; doEncrypt: boolean);
var Thread: array[0..3] of TThreadParams; // faster than dynamic array
Handle: array[0..3] of THandle; // high(Thread) is not compiled by XE2
nThread, i, nOne: integer;
pIn, pOut: PAESBlock;
begin
if Count=0 then exit;
if {$ifdef USEPADLOCK} padlock_available or {$endif}
(SystemInfo.dwNumberOfProcessors<=1) or // (DebugHook<>0) or
(Count<((512*1024) div AESBlockSize)) then begin // not needed below 512 KB
DoBlocks(bIn,bOut,bIn,bOut,Count,doEncrypt);
exit;
end;
nThread := SystemInfo.dwNumberOfProcessors;
if nThread>length(Thread) then // a quad-core is enough ;)
nThread := length(Thread);
nOne := Count div nThread;
pIn := bIn;
pOut := bOut;
for i := 0 to nThread-1 do
with Thread[i] do begin // create threads parameters
bIn := pIn;
bOut := pOut;
BlockCount := nOne;
Encrypt := doEncrypt;
AES := self; // local copy of the AES context for every thread
Handle[i] := CreateThread(nil,0,@ThreadWrapper,@Thread[i],0,ID);
inc(pIn,nOne);
inc(pOut,nOne);
dec(Count,nOne);
end;
if Count>0 then
DoBlocks(pIn,pOut,pIn,pOut,Count,doEncrypt); // remaining blocks
inc(Count,nOne*nThread);
assert(integer(pIn)-integer(bIn)=Count*AESBlockSize);
assert(integer(pOut)-integer(bOut)=Count*AESBlockSize);
bIn := pIn;
bOut := pOut;
WaitForMultipleObjects(nThread,@Handle[0],True,INFINITE);
for i := 0 to nThread-1 do
CloseHandle(Handle[i]);
end;