TParallel.Forが想定した動作になりませんコードサンプルを見ていただけますか

解決


jiro  2024-04-20 20:34:38  No: 151454

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;
を並列処理に書き換えたくて作成したコードですが
実際には違った処理に終わります
どなたか解説をしていただけませんでしょうか。


AAAAA  2024-04-21 03:28:17  No: 151455

https://docwiki.embarcadero.com/RADStudio/Sydney/ja/%E4%B8%A6%E5%88%97%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0_%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%AE_TParallel.For_%E3%81%AE%E4%BD%BF%E7%94%A8

>並列ループ内で、オペレーションをスレッドセーフのオペレーションに変換しなければなりません。System.SyncObjs ユニットのメンバー(TInterlocked メソッドなど)を使用することができます。


jiro  2024-04-21 10:25:22  No: 151456

オンラインヘルプを見てご指摘のメンバー利用法が思いつかなかったのでこちらに投稿する以前にTThread.Synchronizeを用いてメインスレッドにアクセスを考えておりました。ウェブで調査するとTTaskで囲うような記述でなければ動作が呈するということでその通り回避策をとりましたが実行に難がありましたので質問させていただいた次第です。
それ以外に具体的な解決法があればご提示ください。よろしくお願いいたします。
使用先は複雑なアプリケーションですので複数回答があれば柔軟な方法を推奨してくださいますと助かります。


AAAAA  2024-04-21 13:27:30  No: 151457

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.


jiro  2024-04-21 15:01:15  No: 151458

AAAAA  様、ご回答感謝します。初めてぐらいにTParallel.Forを動かした気がします。
私のソフトウェアでの応用も考えましたが、元来ループ箇所が少ない並列処理の恩恵を受けづらいコードだったのかもしれません。
題名にある問題は独力で解決できないよい解法が与えられているので質問は解決にして閉じさせていただきます。
相談に応じてくださりありがとうございました。


※返信する前に利用規約をご確認ください。








  このエントリーをはてなブックマークに追加