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

该程序将仍然被执行,当我暂停在Visual Studio中它会暂停,其中i具有平行过程对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去道琼斯指数后缀树,直到它会等待直到没有线程向阵列列表添加任何对象

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'最终终止。如果它?这是通过设计来实现的,它终止了线程池中的所有线程e旋转以满足您的要求。如果它不终止,是否有一些边界条件使一个或多个线程处于打开状态? – 2013-03-27 20:14:16

+0

在程序中,它应该终止,但在这种情况下,它不应该在那个阶段,因为并不是所有的数据都会被处理。此后,它应该达到一个永远不会达到的断点,并且程序只是挂在foreach上。 – 2013-03-27 20:16:11

+0

是否有可能将输出解释为处理终止,实际上它可能只是因为'Parallel.ForEach'不再需要这些线程,因此将它们释放到ThreadPool中?如果你想要一个更具体的答案,你需要告诉我们更多关于你的断点的信息:它在哪里,代码是什么,以及你为什么期望它被击中。 – 2013-03-27 20:25:54

回答

1

抛弃“标志”变量并使用锁定语句。在这段代码中,可能有多个线程处于关键部分(即一个线程将设置flag = true,而另一个线程将flag == false评估为true(未来只使用!标志)

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

将谢谢。 – 2013-03-27 21:39:40

+0

如果发生这种情况,即两个线程立即进入,那么视觉工作室不会将其指定为例外吗? – 2013-03-27 21:48:41

+0

调试并行性问题非常困难,并且线程的等待对于调试器而言并不是问题......也许您正在等待非常长的异步操作才能完成。 – Moho 2013-03-27 21:52:49