multithreading - 并行处理 - 连接数据

标签 multithreading algorithm parallel-processing mapreduce multiprocessing

问题

摘要:将函数 F 并行应用于数组的每个元素,其中 F 不是线程安全的。

我有一组元素 E 要处理,可以说是一个队列。 我想使用相同的函数 f( E ) 并行处理所有这些元素。

现在,理想情况下我可以调用基于map 的并行模式,但该问题具有以下约束。

  • 每个元素包含一对 2 个对象。( E = (A,B) )
  • 两个元素可以共享一个对象。 ( E1 = (A1,B1); E2 = (A1, B2) )
  • 函数 f 不能处理共享一个对象的两个元素。所以 E1 和 E2 不能并行处理。

这样做的正确方法是什么?

我的想法是这样的,

  1. 琐碎的想法:保留一组事件的 As 和 B,仅当没有其他线程已经在使用 A 或 B 时才开始处理元素。
    • 因此,当您将元素提供给线程时,您会将 As 和 B 添加到事件集中。
    • 选择第一个元素,如果它的元素不在事件集中产生一个新线程,否则将它推到元素队列的后面。
    • 这样做直到队列为空。
    • 这会导致死锁吗?理想情况下,当处理结束时,某些元素将变得可用,对吧?

2.-另一个想法是制作这些连接对象的图表。 每个节点代表一个对象 (A/B) 。每个元素都是连接 A 和 B 的边,然后以某种方式处理数据,使我们知道元素永远不会重叠。

问题

  • 我们怎样才能做到最好?
  • 是否有执行此操作的标准模式?
  • 这些方法有问题吗?
  • 不是必需的,但如果您能告诉 TBB 方法使用,那就太好了。

最佳答案

“最佳”方法取决于很多因素:

  1. 你有多少元素“E”,f(E) 需要多少功。 --> 检查并行处理这些元素是否真的值得(如果您需要大量锁定并且没有太多工作要做,您可能会通过并行处理来减慢进程)
  2. 是否有可能更改使 f(E) 多线程安全的设计?
  3. 有多少个元素“A”和“B”?元素“E”共享特定版本的 A 和 B 是否存在任何逻辑? --> 如果您可以将元素 E 分类到单独的列表中,其中每个 A 和 B 仅出现在一个列表中,那么您可以并行处理这些列表而无需任何进一步锁定。
  4. 如果有许多不同的 A 和 B,而您并没有共享太多,您可能想采用一种简单的方法,即在进入时锁定每个“A”和“B”,然后等待直到获得锁。

每当您使用多个锁进行“锁定并等待”时,务必始终以相同的顺序获取锁(例如始终先获取 A,然后获取 B),否则您可能会遇到死锁。这个加锁顺序需要在任何地方都遵守(整个应用程序中的一个地方使用不同的顺序可能会导致死锁)

编辑:此外,如果您执行“尝试锁定”,您需要确保顺序始终相同。否则你可能会导致生命锁:

  1. 线程 1 锁 A
  2. 线程2锁B
  3. 线程 1 试图锁定 B 但失败了
  4. 线程 2 试图锁定 A 但失败了
  5. 线程1释放锁A
  6. 线程2释放锁B
  7. 转到 1 并重复...

这种情况实际上“无休止”发生的可能性相对较小,但无论如何都应该避免

编辑 2: 主要是我想我只是根据 Ax 将 E(Ax, Bx) 分成不同的列表(例如,共享相同 A 的所有 E 的一个列表)。然后在锁定“B”的同时处理这些列表(如果所需的 B 已被使用,您仍然可以“TryLock”并继续。

关于multithreading - 并行处理 - 连接数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24449001/

相关文章:

c++ - 生成一个范围内的随机数,其中的百分比为特定值

parallel-processing - POCL(可移植计算语言)和OpenCL有什么区别?

algorithm - 最快的阴影算法是什么(仅限 CPU)?

algorithm - 为什么A*的复杂度在内存中呈指数级增长?

mysql - 如何避免将大型文件并行加载到mysql中的超时错误

c# - 如何在不冒应用程序失败风险的情况下调用 SemaphoreSlim.Release()?

java - mysql中如何使用多线程取数据

java - 即使在同步后仍存在竞争条件

java - 当线程抛出异常时会发生什么?

Python线程错误,有人有解决方案吗?