我正在寻找一种并发算法,它可以帮助我检测有向图中的周期。
我知道顺序算法使用带着色的dfs,但我认为它会在多线程环境中失败。有向图的一个例子来说明它:
A->(B,C),B-> (D),D-> (E),C-> (E),E-> (F)
A
/ \
B C
| |
D |
\ /
E
|
F
(我希望上面说清楚。图中的边缘都是顶部的)
对于上述有向图,在并发执行期间可以执行以下操作。
(我假设的着色方案是白色 - 未访问,灰色 - 执行dfs未完成和黑色 - 完成执行和访问)
Dfs(B)由线程1,最终将E颜色为灰色并执行dfs(E)(导致F)。在此之前,线程2执行dfs(C)。它意识到E是灰色的并报告一个明显不是这种情况的循环。
我检查过Tarjan的算法也可以用于循环检测,但我不认为它的执行在多线程环境中是正确的。
有人可以帮我解决这个问题吗?
感谢。
答案 0 :(得分:1)
正如Ira所说,让每个线程都使用自己的颜色。
但是,如果您有固定数量的线程,则为每种颜色使用位图。 因为,只要您的处理器支持原子位测试并设置(即x86上的BTST),您就不会需要锁定事件,因为每个线程都将测试并设置不同的位。
如果设置了该位,则该项目将显示为灰色。
PS:如果您需要更多颜色,那么您可以使用更多位。
答案 1 :(得分:1)
对于多线程循环检测,最好使用Kahn算法的变体(用于拓扑排序)而不是DFS。这使用了以下事实:
1)如果有向图是非循环的,那么它至少有一个没有内边的顶点,至少有一个没有外边的顶点;
2)没有边缘或没有外边缘的顶点不能参与循环;所以
3)如果删除没有内边缘或没有外边缘的顶点,则会留下一个较小的有向图,其周期与原始周期相同。
因此,要进行并行周期检测,您可以:
1)首先,使用并行BFS构建一个数据结构,跟踪每个顶点的度数和出度。
2)然后,并行地删除具有in-degree或out-degree 0的顶点。注意,删除顶点将减小相邻节点的in-degrees或out-degree。
3)当您从顶点移除以移除时,您将离开周期中涉及的所有顶点。如果没有,那么原始图表是非循环的。
并行BFS(步骤1)和并行顶点删除(步骤2)都可以通过并行工作队列轻松完成。在步骤1中,当您第一次看到顶点时,将任务添加到处理相邻顶点的队列中。在步骤2中,当您将顶点的度数或度数递减为0时,添加一个任务以将其从图表中删除。
请注意,如果仅删除具有度为0的in-degree 0 或节点的节点,则此算法也可以正常工作,但并行机会有所减少。
答案 2 :(得分:0)
您应该很容易找到解决周期检测问题的分布式死锁检测算法。
我知道分布式并不完全是多线程的,但你仍然应该在那里找到提示。
编辑:添加了限制解决方案。