2013-03-27 5 views
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). 

программа будет по-прежнему выполняет и когда я паузу в визуальной студии он делает паузу, где я есть параллельный порядок 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]]); 
     } 
    } 
); 

Я не думаю, что его мертвое блокировки причины не существует ни одного случая, где может быть поток, ожидающий различных ресурсов и evetually блокировки друг друга

он должен войти внутрь этого метода и recursivley идти Dow дерево суффикса недо он будет ждать до тех пор, пока нить не добавит объект к архаисту

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]] 
      ); 
      } 
     } 
+0

Имеет ли 'Parallel.ForEach' в конце концов прекратить Если это? делает это по-дизайну. Он завершает все потоки в пуле потоков, которые wer e, чтобы удовлетворить ваш запрос. Если это не заканчивается, существует ли какое-то граничное условие, которое удерживает один или несколько потоков открытым? –

+0

В программе предполагается прекратить работу, но в этом случае он не должен находиться на этом этапе, поскольку не все данные были бы обработаны. Также после этого предполагается достигнуть точки останова, которая никогда не достигается, и программа просто зависает в foreach. –

+0

Возможно ли, что вы интерпретируете вывод как завершение обработки, когда на самом деле может быть просто, что 'Parallel.ForEach' просто больше не нуждается в этих потоках и поэтому выпускает их в ThreadPool? Если вам нужен более конкретный ответ, вам нужно будет рассказать нам немного больше о вашей точке останова: где это, какой код есть и почему вы ожидаете, что его ударят. –

ответ

1

Отрежьте переменную 'flag' и используйте оператор блокировки. Возможно, что более чем один поток находится в вашем критическом разделе с этим кодом (т. Е. Один поток собирается установить флаг = true, а другой поток только что оценил флаг == false как истинный (в будущем он будет использовать только флаг!)

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]]); 
    } 
} 
+0

будет спасибо. –

+0

, если такая вещь произойдет, то есть два потока входят сразу, разве визуальная студия не указала бы это как исключение? –

+0

Проблемы отладки параллелизма очень сложны, и ожидание потоков не является проблемой в отношении отладчика ... может быть, вы ожидаете завершения очень продолжительной асинхронной операции. – Moho

Смежные вопросы