Geo*_*lly 2 python multithreading locks
我遇到了需要以下模式的功能:
from threading import Lock
the_list = []
the_list_lock = Lock()
Run Code Online (Sandbox Code Playgroud)
并使用它:
with the_list_lock:
the_list.append("New Element")
Run Code Online (Sandbox Code Playgroud)
不幸的是,这并不需要我获取锁,我可以直接访问该对象.我希望得到一些保护(我只是人类.)有没有一种标准的方法来做到这一点?我自己的方法是创建一个HidingLock可以像这样使用的类:
the_list = HidingLock([])
with the_list as l:
l.append("New Element")
Run Code Online (Sandbox Code Playgroud)
但它感觉非常基本,它应该存在于标准库中,或者它是一种非常规的使用锁的方式.
我认为标准库中没有任何东西的原因是因为它存在,它需要制作铸铁访问保证.提供更少的东西会给人一种虚假的安全感,这可能导致同样多的并发问题.
在没有做出实质性的牺牲的情况下,几乎不可能做出这些保证.因此,用户需要考虑如何管理并发问题.这符合Python的一个哲学,即"我们都同意成年人".也就是说,如果你正在编写一个类,我认为在访问属性之前你应该知道获取锁所需的属性是合理的.或者,如果您真的那么关心,请编写一个包装器/代理类来控制对底层对象的所有访问.
在您的示例中,目标对象可能会以多种方式意外地逃脱.如果程序员没有足够重视他们编写/维护的代码,那么这HiddenLock可能会提供错误的安全感.例如:
with the_lock as obj:
pass
obj.func() # erroneous
with the_lock as obj:
return obj.func() # possibly erroneous
# What if the return value of `func' contains a self reference?
with the_lock as obj:
obj_copy = obj[:]
obj_copy[0] = 2 # erroneous?
Run Code Online (Sandbox Code Playgroud)
最后一个特别有害.此代码是否是线程安全的,不取决于with块中的代码,甚至取决于块之后的代码.相反,它的类的obj实现将意味着此代码是否是线程安全的.例如,如果obj是a list那么这是安全的,因为obj[:]创建副本.但是,如果obj是a numpy.ndarray然后obj[:]创建一个视图,那么操作是不安全的.
实际上,如果内容obj是可变的,那么这可能是不安全的(例如obj_copy[0].mutate()).
| 归档时间: |
|
| 查看次数: |
2983 次 |
| 最近记录: |