lis*_*tor 7 hash multithreading semaphore push raku
我有一个巨大的数据文件(接近 4T)需要处理。我在我的 4 核 CPU 上使用 4 个线程。第一个线程分析文件的第一部分,依此类推。所有线程在分析了自己四分之一的数据文件的部分后,都需要将它们的结果添加到相同的单个散列和单个数组中。那么,散列和数组的“推送”和“弹出”以及“移位”和“取消移位”操作是原子和线程安全的,还是我必须求助于更复杂的机制,如信号量?
Jon*_*ton 10
不,它们既不是原子的也不是线程安全的,从多个线程使用会导致崩溃或数据不一致。
也就是说,即使是这样,当您添加更多线程时,在同一数据结构上涉及大量争用的设计也会很差。这是因为硬件在面对并行时的工作方式;简要地:
您可以使用锁定来获得正确性。为此,我不建议直接使用锁,而是查看类似 的模块OO::Monitors
,您可以在其中将散列封装在一个对象中并在边界处完成锁定。
如果与生成要推送的项目所做的工作量相比,您在共享数据结构上执行的推送数量较少,那么您可能不会在锁定和围绕数据结构的争用方面遇到瓶颈。但是,如果您push
每秒执行数千个es 或类似操作,我建议您寻找替代设计。例如:
start
触发每个工人,它返回一个Promise
. 将Promise
s 放入数组中。Promise
返回它产生的项目的数组或散列。my @all-results = flat await @promises;
或类似的就足以将所有结果收集在一起。您可能会发现您的问题非常适合并行迭代器范式,使用 hyper 或 Race,在这种情况下,您甚至不需要自己分解工作或设置工作人员;相反,您可以选择程度和批量大小。