Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中线程之间共享DICT时,是否可以避免锁定开销?_Python_Multithreading_Immutability - Fatal编程技术网

在Python中线程之间共享DICT时,是否可以避免锁定开销?

在Python中线程之间共享DICT时,是否可以避免锁定开销?,python,multithreading,immutability,Python,Multithreading,Immutability,我有一个Python中的多线程应用程序,其中线程读取非常大(因此我无法将它们复制到线程本地存储)的DICT(从磁盘读取,并且从未修改)。然后,他们使用DICT作为只读数据处理大量数据: # single threaded d1,d2,d3 = read_dictionaries() while line in stdin: stdout.write(compute(line,d1,d2,d3)+line) 我试图通过使用线程来加速这个过程,然后每个线程读取自己的输入并写入自己的输出,但

我有一个Python中的多线程应用程序,其中线程读取非常大(因此我无法将它们复制到线程本地存储)的DICT(从磁盘读取,并且从未修改)。然后,他们使用DICT作为只读数据处理大量数据:

# single threaded
d1,d2,d3 = read_dictionaries()
while line in stdin:
    stdout.write(compute(line,d1,d2,d3)+line)
我试图通过使用线程来加速这个过程,然后每个线程读取自己的输入并写入自己的输出,但是由于dict很大,我希望线程共享存储

IIUC,每次线程读取dict时,它都必须将其锁定,这会给应用程序带来性能成本。这种数据锁定是不必要的,因为DICT是只读的

CPython实际上是单独锁定数据还是只使用


如果确实存在每dict锁定,有没有办法避免它?

python中的多线程处理是无用的。最好使用多处理模块。因为多线程只能在较少的情况下发挥积极作用

Python实现细节:在CPython中,由于 解释器锁,一次只能有一个线程执行Python代码 (即使某些面向性能的库可能会克服 这一限制)。如果您希望应用程序更好地利用 多核机器的计算资源,建议您 使用多处理。然而,线程仍然是一种合适的模型 如果要同时运行多个I/O绑定任务。

如果您没有任何代码示例,我只能建议将您的大词典拆分为几个部分,并使用。并在主进程中合并结果

不幸的是,在不同的python进程之间共享大量内存是不可能的(我们不是在讨论基于的共享内存模式)。但你可以在不同的过程中阅读词典的不同部分。或者只需在主进程中阅读整个字典,然后给子进程一小块

另外,我应该警告您,您应该非常小心地使用多处理算法。因为每增加一兆字节,进程的数量就会成倍增加

因此,基于您的伪代码示例,我可以假设基于
compute
函数的两种可能算法:

# "Stateless"
for line in stdin:
    res = compute_1(line) + compute_2(line) + compute_3(line)
    print res, line

# "Shared" state
for line in stdin:
    res = compute_1(line)
    res = compute_2(line, res)
    res = compute_3(line, res)
    print res, line
在第一种情况下,您可以创建多个worker,根据不同的worker读取每个字典(最好减少每个进程的内存使用),然后像生产线一样进行计算


在第二种情况下,您拥有一个共享状态。对于下一个工人,您需要上一个工人的结果。这是多线程/多处理编程的最坏情况。但您可以编写算法,在那个里,几个工作人员使用相同的队列并将结果推送到它,而不必等待所有周期的完成。您只需在您的进程之间共享一个实例。

请发布一个示例代码,说明您现在正在做什么。当您说“锁定开销”时,具体指的是什么?我怀疑全局解释器锁可能是最大的问题,但是从这个问题来看,还不清楚开销是如何具体到DICT的。。。但不知何故,我不认为这正是你想要的。。。为什么不把dicts加载到logparse中,或者仅仅加载到redis中呢?如果您使用Jython或IronPython(我认为两者都不支持Python 3),那么它们就没有GIL。我认为使用CPython(来自Python.org)没有任何方法可以做到这一点,但您可能能够做到。不过,对于您的用例,我不确定。@Jimilian:done-我希望这能澄清我的意图。我会在子进程之间共享dicts使用的内存吗?@sds,我在回答中添加了一些关于内存共享的细节。