program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, Threading;
begin
try
{ TODO -oUser -cConsole メイン : ここにコードを記述してください }
TParallel.For(0,9,
procedure(i: integer)
begin
Writeln(i);
end);
Writeln('end');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
これは私が
for var i:=0 to 9 do
begin
Writeln(i);
end;
を並列処理に書き換えたくて作成したコードですが
実際には違った処理に終わります
どなたか解説をしていただけませんでしょうか。
>並列ループ内で、オペレーションをスレッドセーフのオペレーションに変換しなければなりません。System.SyncObjs ユニットのメンバー(TInterlocked メソッドなど)を使用することができます。
オンラインヘルプを見てご指摘のメンバー利用法が思いつかなかったのでこちらに投稿する以前にTThread.Synchronizeを用いてメインスレッドにアクセスを考えておりました。ウェブで調査するとTTaskで囲うような記述でなければ動作が呈するということでその通り回避策をとりましたが実行に難がありましたので質問させていただいた次第です。
それ以外に具体的な解決法があればご提示ください。よろしくお願いいたします。
使用先は複雑なアプリケーションですので複数回答があれば柔軟な方法を推奨してくださいますと助かります。
var
CS: TRTLCriticalSection;
begin
InitializeCriticalSection(CS);
try
{ TODO -oUser -cConsole メイン : ここにコードを記述してください }
TParallel.For(0,9,
procedure(i: integer)
begin
EnterCriticalSection(CS);
Writeln(i);
LeaveCriticalSection(CS);
end);
Writeln('end');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
DeleteCriticalSection(CS);
end.
AAAAA 様、ご回答感謝します。初めてぐらいにTParallel.Forを動かした気がします。
私のソフトウェアでの応用も考えましたが、元来ループ箇所が少ない並列処理の恩恵を受けづらいコードだったのかもしれません。
題名にある問題は独力で解決できないよい解法が与えられているので質問は解決にして閉じさせていただきます。
相談に応じてくださりありがとうございました。
ツイート | ![]() |