2016-11-07 17 views
-2

アイデアを記述するMCVEは次のとおりです。このAnonymousThreadの実装は正しいですか?

type 
    TMyRecord = record 
    FLastResult: double; 
    procedure DoHeavyMath(Input: double); 
    end; 
var 
    MyRecordArray:array [0..999] of TMyRecord; 
    InputData:array [0..999] of double; 
implementation 

procedure TMyRecord.DoHeavyMath(Input: double); 
begin 
    FLastResult:=Input;//Here should be some math 
end; 

私は匿名のスレッドを作成していますし、プロセスの数を制限する(スレッド:入力パラメータを受け取り、その変数の一つに格納されたいくつかの結果を計算する方法を持っているクラス/レコードの配列があります)同時に働く。

procedure TForm1.Button1Click(Sender: TObject); 
var 
    ThreadsCounter, i: word; 
begin 
    ThreadsCounter := 0; 

    for i := 0 to 999 do 
    begin 
    while ThreadsCounter >= 4 { or other limit } do 
    begin 
    end; 

    inc(ThreadsCounter); 
    TThread.CreateAnonymousThread(
     procedure 
     begin 
     MyRecordArray[i].DoHeavyMath(InputData[i]); 
     dec(ThreadsCounter) 
     end).Start; 
    end; 
    repeat 
    until ThreadsCounter = 0; 
    // return to main thread tasks 
end; 

このスレッドの実装は正しいですか?

+0

私はあなたのコードをテストしたと仮定し、それが「正しい」と考えているので、この質問を議論の対象外としています。実際にコードレビューを求めています。 – GhostCat

答えて

2

いいえ正しくありません。 ThreadsCounterにデータ競争があります。代わりにアトミック関数を使用してください(例:AtomicDecrement)。

スレッドの作成時に大きなオーバーヘッドが発生するため、パフォーマンスがあまり良くありません。代わりにスレッドプールを使用して、スレッドを再利用できるようにします。ビジーなループはパフォーマンスを1ビット助けにはなりません。

+0

私はQを元に戻してしまったので、悪いQを削除することを奨励しています。私は、評価の低い自分のQを削除するためのバスケットがあることを思い出させることができます。 –

+0

'inc'と' dec 'を 'Atomic [Increment | Decrement]'に変更すると、外部例外C000001Dが発生します。 –

+0

正しいとは言えません。ありがとうございます。私のためにうまく動作します。おそらく、あなたのデルファイコンパイラでの変数キャプチャに問題があります。 InterlockedIncrementはこれより優れています。 –

関連する問題