3

假设我有一个无向图。

图的一小部分:

A -----\
        C
B -----/

现在节点 A 和 B 继续并行修改节点 C。 // 节点 A 和节点 B 在并行线程中处理节点 C。

我希望节点 B 的线程将等待节点 A 的线程完成处理。它必须是这样的。没有其他办法。

我也不希望正在处理其他节点的其他线程等待上述条件,即我不想使用互斥锁。

我创建了一个类成员布尔标志,并希望将其用作条件。// 让那个标志为 d_flag

此处的 MT 使用多个 CPU。

我认为不起作用的解决方案:

CPU1:线程 1

while (d_flag) {
    // busy waiting
}
d_flag = true;

// Critical Section

d_flag = false;

CPU2:线程 1

while (d_flag) {
   // busy waiting
}

d_flag = true;

// Critical Section

d_flag = false;

我的理解是,如果在多个 CPU 中,节点 A 线程在 CPU1 上运行,而节点 B 线程在 CPU 2 上运行,则自旋锁被击败。

由于 while 循环中的测试不再是原子的,因此可能存在两种 while 循环的计算结果为 false 的情况。

我的理解对吗??????如果是,是否有不使用整体互斥锁的解决方案。

4

1 回答 1

1

我建议创建一个条件分支,该分支仅在正在处理的节点是 C 时执行。在该分支中,您可以为节点 B 线程设置一个条件变量,以等待节点 A 线程完成处理节点 C。假设您知道线程与节点关联的 ID,我想这很容易实现(至少天真。)如果您不确定节点 A 的线程是否会完成处理节点 C,您可能希望实现一个带有超时的条件变量。

如果我可以提出建议,您的用例对特定线程的节点上的操作顺序有限制,这表明您可能需要考虑一种并行编程范式,它允许您在更高的抽象级别上表达这些想法。也许使用演员模式会有所帮助?

这是一个我认为它对 C++ 非常有用的实现:

https://github.com/Neverlord/libcppa

http://libcppa.blogspot.com/

使用这样的模式,您可以让您的参与者(线程)就他们处理了哪些节点进行通信,并根据这些通信控制他们的流程。因此,例如,您可以让节点 A 参与者在完成处理节点 C 时通知节点 B 参与者。这允许节点 B 参与者在等待来自 A 的消息时做其他事情。

于 2014-07-21T13:25:46.460 回答