Python程序创建锁的数量是否有限制?

7
我有一个单线程的Python3程序,现在想将其转换为多线程。我有一个类似树形结构的数据结构需要读取和写入,可能会有多个线程同时读取和写入。
一种显而易见的方法是为整个数据结构设置一个锁:当正在进行写操作时,没有人可以读取,最多只能同时进行一次写操作,并且在有待处理的读操作时不能进行写操作。
但是,为了提高性能,我希望将锁定更加细粒度化。这是一个完整的16叉树,当完全填充时,有大约5到6百万个叶子节点(在实践中大多数都是平衡的,但不保证)。如果我想要最细粒度的锁定,我可以锁定叶子节点的父节点。这意味着需要超过100,000个锁。
我必须承认,我还没有尝试过。但是我想先问一下:是否有任何硬件限制或性能原因应该阻止我创建这么多锁对象?也就是说,我应该只考虑从根节点向下锁定到第2层(256个锁)吗?
谢谢您的任何见解。
编辑:
更多细节:
我还不知道有多少个核心,因为我们仍在试验,看看我们需要多少计算能力,但我猜只会使用几个核心。
我打算使用大约50,000个线程。有异步I / O和一个套接字每个线程。在代码的引导阶段,尽可能多的线程将同时运行(由硬件限制),但这是一次性的成本。我们更感兴趣的是一旦事情开始运行。那时,我猜每秒只有几千个线程正在运行。我需要测量响应时间,但我猜唤醒周期大约为10ms。这是一次有几十个线程同时活动(平均值)。
现在我写出来了,也许这就是我的问题的答案。如果我一次只需要几十个线程读取或写入,那么我实际上不需要在树上进行如此细粒度的锁定。

2
如果您可以访问256核CPU,请开始吧。此外,我认为您应该阅读一些关于线程的一般信息。google://threads+overhead - strangeqargo
2
@ArmadilloJim 创建超过 CPU 核心数量的线程没有任何好处。 - Brendan Abel
1
相关链接:http://code.activestate.com/recipes/502283-read-write-lock-class-rlock-like/ - Robᵩ
@BrendanAbel 这不是关于并行性,而是关于并发性。这是异步I/O的必要工作。 - Armadillo Jim
2
经过一个非常简单的测试,除了内存空间之外,创建锁没有任何其他限制(在尝试在列表中创建 sys.maxsize 锁时收到了有关内存的警告)。 - Tadhg McDonald-Jensen
显示剩余7条评论
2个回答

4

过早优化

这是一个经典的过早优化例子。如果不知道线程花费多少时间阻塞,也就是等待其他写操作完成,那么管理成千上万个锁所带来的复杂性对你而言并没有什么好处。

全局解释器锁

使用线程可能是一种过早的优化。你的任务是否容易进行线程处理?许多线程可以安全地并行工作吗?需要大量共享状态(即许多和频繁的锁)的任务通常不适合高线程数量。在Python中,由于GIL的存在,你可能会看到更少的好处。你的线程是否正在进行大量的IO、调用外部应用程序或使用以C编写的Python模块来正确释放GIL?如果没有,线程实际上可能不会给你带来任何好处。你可以通过使用multiprocessing模块来避开GIL,但在跨进程边界传递锁和写入时会有开销,具有讽刺意味的是,它可能会使你的应用变得更慢。

队列

另一个选择是使用写队列。如果线程实际上不需要共享状态,但它们都需要写入同一个对象(即很少从该对象读取),那么你可以将写入添加到队列中,并使用单个线程处理写入,无需任何锁。


从技术上讲,队列在第一时间使用锁来保证线程安全。 - Tadhg McDonald-Jensen
关于过早优化的观点很好。请查看我对问题的更新,其中包含更多的估计数据。仅锁定树的顶层(或者可能是第二层)应该就足够了。 - Armadillo Jim
我认为在我的情况下它最终并不会有用,但写入队列是个好主意。谢谢! - Armadillo Jim

2
回应 Brendan Abel 的话:避免过早优化。如果我有16个核心,就不能有超过16个并行访问(读/写)。没有必要挂着很多锁。一定数量的锁就足够了。问题变成了:如果我在一组资源上进行随机访问,两个核心同时尝试访问同一个资源的机会是多少?
例如,如果我有16个核心尝试随机访问16个资源,则一个阻止另一个的机会很高。也就是说,在16个对象与16个对象的独立选择之间,排列组合很少:16!与16^16相比,不被阻塞的机会约为100万分之一。(注意:我在问题下方的早期评论是错误的)另一方面,如果我有16个核心随机访问256个资源,则阻塞的机会降至约38%。当你达到16个核心和4096个资源时,阻塞的机会低于3%。
这与生日悖论有关。
注意:我在这里假设一个线程阻塞另一个是不可取的,等待是不可接受的。但是,正如上面所述,要做的就是测量。不要把更多的工程努力投入到优化某些根本不需要的东西中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接