python - 为什么使用锁来读/写共享内存比不使用锁要快
问题描述
我正在试验 Python 多处理,我很惊讶在使用锁时看到反直觉的结果。
我的假设是,在使用共享内存时,如果我们使用锁来确保一次只有一个进程可以访问共享对象,那么所有其他进程将等待锁定进程释放锁,然后再读取/写入共享对象. 因此,尽管这确保了数据完整性并消除了竞争条件,但这也不可避免地导致除了一个进程之外的所有进程都在等待锁定进程。结果,执行的总时间将比不使用锁时长。如果不使用锁,所有进程都不会相互等待,因此会更快完成,但也会损坏数据。
考虑到这种理解,我编写了一个快速程序来确定使用锁到底慢了多少,但令人惊讶的是,使用锁似乎实际上要快得多。
你能解释一下为什么使用锁更快吗?我对锁如何工作的理解有问题吗?或者我设置实验的方式有问题(下面的代码)。
如果lock.acquire()
和lock.release()
被注释掉,所以不使用锁,它需要75.85秒,
如果lock.acquire()
和lock.release()
被取消注释,所以使用锁,需要57.17秒
我使用 Python 3.7,在 Intel i7 8550U 上运行,4 个物理内核,(8 个超线程线程)
import os
import multiprocessing as mp
from timeit import default_timer as timer
def func(n, val, lock, add):
for i in range(n):
lock.acquire() # uncomment to use lock
if add:
val.value += 1
else:
val.value -= 1
lock.release() # uncomment to use lock
if i % (n/10) == 0:
print(f"Process: {os.getpid()}, {(i / n * 100):.2f}%")
if __name__ == "__main__":
start = timer()
lock = mp.Lock()
n = 2000000
val = mp.Value('i', 100)
arr = mp.Array('i', 10)
p1 = mp.Process(target=func, args=(n, val, lock, True))
p2 = mp.Process(target=func, args=(n, val, lock, False))
p1.start()
p2.start()
p1.join()
p2.join()
elapsed = timer() - start
print("Time elapsed = {}".format(elapsed))
print(f"Val = {val.value}")
解决方案
推荐阅读
- python - 外部嵌套循环 Python 的累加器
- php - TWIG:从字符串中修剪两个字符
- sql-server - 在 xml 节点 SQL Server 上迭代值
- c# - 如何使用 Unity.WebApi 通过接口实例访问类属性
- python - 如何使用 re.sub
- python - 我有两个我知道是相等的变量,但我的 if 语句不承认这一点?
- fluent - 使用字符串枚举创建 Fluent 模型
- php - 尝试上传文件php时出现oci_excute错误
- css - CSS 剪辑路径在元素堆栈顺序之前中断伪 ::before
- javascript - 从 javascript 访问 mongodb+nodjs?