python - multiprocessing.Lock 是否在其上下文中暂停程序?
问题描述
我想知道 GIL Lock 类是否暂停程序或跳过其中的上下文,以防锁被另一个线程持有
from multiprocessing import Lock
from threading import Thread
import pandas as pd
# Thread 1
def th1(lock1):
while True:
with lock1: # does the program pause/wait here in case lock is held by Th2 or simply skip the context within lock1?
df1 = pd.read_csv('foo.csv')
# do some work with df1
# Thread 2
def th2(lock2):
while True:
with lock2: # does the program pause/wait here in case lock is held by Th1 or simply skip the context within lock2?
df2 = pd.read_csv('foo.csv')
# do some work with df2
if __name__ == "__main__":
th_lock = Lock()
th1_th = Thread(target=th1, daemon=False, kwargs:{'lock1':th_lock}
th2_th = Thread(target=th2, daemon=False, kwargs:{'lock2':th_lock}
th1_th.start()
th2_th.start()
解决方案
简单的答案
如果Lock
在with
语句中使用 a ,它将阻塞线程,直到获得锁,然后执行套件:
with some_lock:
do_all_the_things()
如果你想偷看锁,你可以手动获取,如果成功则只执行锁定的代码
if some_lock.acquire(block=False):
try:
do_all_the_things() # only executed if lock acquired immediately
finally:
some_lock.release()
或者,对于超时
if some_lock.acquire(timeout=4.2):
try:
do_all_the_things() # only executed if lock acquired before timeout
finally:
some_lock.release()
复杂的答案
获取锁的步骤因操作系统而异,但一般步骤是
- 尝试获得锁
- 成功,返回
- 释放吉尔
- 等待锁
- 获得吉尔
- 返回
获得锁的第一个实体继续执行,而不对 GIL 进行任何更改。它在锁上有 GIL(或者它不会运行来获取锁),并将在定期检查间隔释放它以让其他线程运行。
现在另一个线程正在运行并尝试获取锁。该操作释放 GIL,然后等待锁定。由于第一个实体除了等待 GIL 之外没有被阻塞,它再次运行并完成其业务。当它终于可以释放锁时,第二个实体的非 GIL C 代码运行一点点以尝试获取 GIL。但它卡在那里,因为第一个实体仍然有 GIL。
第一个实体将在定期检查间隔终止或释放 GIL,让第二个条目在受锁保护的代码内运行。
请注意,第一个或第二个实体都没有被阻止。它们将根据另一个释放 GIL 的时间进行交错。假设您正试图保护锁中的数据结构。好吧,其他代码正在运行。如果它在锁之外摆弄相同的数据,那么你就有了一个错误。锁没用。这是合作锁定。它只有在每个人都玩游戏时才有效。
推荐阅读
- resilience4j - 将 Prometheus 指标与 CircuitBreakerConfigCustomizer 一起使用
- jmeter - 如何管理客户端证书的大型密钥库以使用 JMeter 加载测试 Mutual TLS
- python - 用python中的字符串替换列表中的多个字符串并获取替换字符串出现的计数
- javascript - Android反应原生接近传感器
- python - sqlalchemy 连接烧瓶
- javascript - 获取请求后重定向需要两次点击?
- objective-c - TVOS 上的 contentOverlayView 未显示
- assembly - 如何在 x86 程序集中将 16 位寄存器移动到 8 位寄存器?
- regex - Delphi中用于StringList中所有匹配行的正则表达式
- c++ - 我是否正确推理缓存性能?