0

データの並列実行に tpl を使用しています。問題は、そのような出力を与える理由もなく時々ハングすることです:

The thread '<No Name>' (0x4aa4) has exited with code 0 (0x0).
The thread '<No Name>' (0x2bf4) has exited with code 0 (0x0).
The thread '<No Name>' (0x417c) has exited with code 0 (0x0).
The thread '<No Name>' (0x432c) has exited with code 0 (0x0).
The thread '<No Name>' (0x3ad0) has exited with code 0 (0x0).
The thread '<No Name>' (0x4440) has exited with code 0 (0x0).
The thread '<No Name>' (0x24e8) has exited with code 0 (0x0).
The thread '<No Name>' (0x3354) has exited with code 0 (0x0).
The thread '<No Name>' (0x4a30) has exited with code 0 (0x0).

プログラムはまだ実行中であり、Visual Studio で一時停止すると、ForEach の並列プロシージャがある場所で一時停止します。

Parallel.ForEach
(
   hold1.remainingHolds.ToArray(), 
   subSequence =>
   {
      //only if subsequence has 1 common substring
      if (checkIfCommon(remainingSequence, subSequence.ToString()) == 1)
      {
         goDownLinkType2(subSequence.ToString().Split(','), 0, 
           (SuffixNode)hold1.childHolds[subSequence.ToString().Split(',')[0]]);
       }
    }
  );

スレッドが異なるリソースを待機し、最終的にお互いをロックする可能性がないため、デッドロックだとは思いません

このメソッド内に入り、再帰的にサフィックスツリーをたどって、スレッドが配列リストにオブジェクトを追加しなくなるまで待機する必要があります

 Boolean flag = false;
 public void goDownLinkType2
      (string[] splittedString, 
       int index, SuffixNode currentNode)
       {
          Boolean writingFlag = false;
          if (index == 2)
          {
             while(writingFlag == false)
             {
                while(flag == true)
                {
        //blocked
                 }
                 if (flag == false)
                 {
                    flag = true;
                 if(!secondChoiceResults.Contains
                     (currentNode.representingStance.SequenceOfHolds))
                 {
                    Console.WriteLine("new addition");
                    secondChoiceResults.Add
                       (currentNode.representingStance.SequenceOfHolds,
                        currentNode.representingStance);
                  }
                  flag = false;
                  writingFlag = true;
               }
            }

         }
         else
         {
            int nextIndex = index + 1;
            goDownLinkType2
              (splittedString, 
               nextIndex,
               (SuffixNode)currentNode.childHolds[splittedString[nextIndex]]
              );
          }
       }
4

1 に答える 1

1

「フラグ」変数を投げて、lock ステートメントを使用します。このコードを使用すると、複数のスレッドがクリティカル セクションに存在する可能性があります (つまり、あるスレッドが flag = true を設定しようとしているときに、別のスレッドが flag == false を true として評価しただけです (将来的には !flag を使用するだけです)。

lock( obj )
{
    // critical section here
}

obj は、すべてのスレッドがアクセスできるオブジェクトへの参照である必要があります。

あなたのコードへの私の変更は次のとおりです。

public void goDownLinkType2(string[] splittedString, int index, SuffixNode currentNode)
{
    Boolean writingFlag = false;
    if (index == 2)
    {
        while(writingFlag == false)
        {
            lock( this )
            //while(flag == true)
            //{
                //blocked
            //}
            //if (flag == false)
            {
                //flag = true;
                if (!secondChoiceResults.Contains(currentNode.representingStance.SequenceOfHolds))
                {
                    Console.WriteLine("new addition");
                    secondChoiceResults.Add(currentNode.representingStance.SequenceOfHolds, currentNode.representingStance);
                }
                //flag = false;
                writingFlag = true;
            }
        }


    }
    else
    {
        int nextIndex = index + 1;
        goDownLinkType2(splittedString, nextIndex, (SuffixNode)currentNode.childHolds[splittedString[nextIndex]]);
    }
}
于 2013-03-27T21:32:40.773 に答える