高效的多线程算法,用于处理没有死锁的对列表

时间:2017-12-14 12:41:48

标签: multithreading algorithm

想象一下,我们有0n-1的整数(让我们说我们有n个图像并使用此索引识别它们)和一对带有这些整数。在这里我们如何创建这些对并不是很重要,但只是为了可视化问题,我们可以说对是那些具有共同区域的图像。

我们的任务是使用多个线程处理所有可用对。如果要求只是每个对都可以被一个线程占用,那么任务就很简单:我们可以使用互斥对象的每个元素。但在我的情况下,情况更加困难:如果某个线程处理一对(m,n),则另一个线程不能使用由mn组成的任何一对。

对每个图像使用互斥锁的简单解决方案是不足的。例如,我们假设我们有图片0,1,2,3和对(0,1)(1,2)(2,3)(3,0)。如果算法对一对使用互斥,然后为每个图像使用两个互斥,则可能出现死锁:th_0将处理对(0,1)th_1 - 对(1,2),{{ 1}} - 对th_2(2,3) - 对th_3。然后每个线程将使用互斥体作为单个图像。

(3,0)

th_0: lock 0, lock 1 th_1: lock 1, lock 2 th_2: lock 2, lock 3 th_3: lock 3, lock 0 将锁定图片th_00会锁定图片th_1,但1会停止,因为它会尝试锁定图片{{1已经锁定的。所有其他线程都会发生同样的情况。

似乎为了实现目标,每个线程必须用对锁定整个向量以避免死锁,这似乎不是一个好的解决方案。这是正确的吗?这个问题有更好的解决方案吗?我想到的唯一解决方案是将互斥锁用于图像以及线程优先级信息。例如,如果第二个图像被锁定,则线程将检查锁定线程的线程ID是否更高,然后它应该释放第一个图像上的锁并继续。它会工作还是我可以再次陷入僵局?

2 个答案:

答案 0 :(得分:5)

当持有资源R1的线程T1尝试获取R2而T2持有R2尝试获取R1时,发生死锁。完全是你的情况。

打破僵局的通常方法是始终以相同的顺序获取资源(如果可能的话)。

在您的情况下,“相同订单”是一个简单的解决方案:首先锁定min(first, second)然后锁定另一个。所以当你在试图锁定“较小”的时候持有“更大”的资源时,你将永远不会结束。

虽然这个解决方案很简单,但它可能不是最理想的,取决于图像处理需要很长时间并且线程经常彼此等待时的争用。

答案 1 :(得分:0)

即使没有死锁,也可能阻塞许多线程等待下一个资源。这可以将并行度降低到最佳水平以下。要提高并行度,必须增加线程数,这需要大量内存。

我看到了两种方法:1)使用一些异步任务并行库,每个任务是处理一些(n,m)对。由于任务使用少量内存,因此您可以在启动时生成所有任务。大量任务承诺高水平的并行性。

然而,最好的结果是动态计算提供最高并行度水平的对的序列。它可以是在专用线程上运行的算法。它从生成N对(0,1),(2,3),...(N-2,N-1)开始。然后它等待下一个任务的结束,并查看是否可以将其他任务提交给执行者。