线程安全的Python属性/属性?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了线程安全的Python属性/属性?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1917字,纯文字阅读大概需要3分钟。
内容图文
我有以下代码:
class SomeSharedData(object):
def __init__(self):
self._lock = RLock()
self._errors = 0
@property
def errors(self):
with self._lock:
return self._errors
@errors.setter
def errors(self, value):
with self._lock:
self._errors = value
除了更多属性,如错误.我的目标是易用性,而不是效率,所以过度锁定很好.
是否有更简洁的方法来定义这些属性?
到目前为止我提出的最好的是:
class thread_safe_property(object):
def __init__(self, name=None):
self.name = name
def __get__(self, obj, objtype):
with obj._lock:
return getattr(obj, self.name)
def __set__(self, obj, val):
with obj._lock:
setattr(obj, self.name, val)
class SomeSharedData(object):
def __init__(self):
self._lock = RLock()
self._errors = 0
errors = thread_safe_property('_errors')
想法?更好的方法?
原始代码和新方法都受到data.errors = 1等语句的可能竞争条件的影响,但我很少需要执行这些操作,因此我在需要时添加了变通方法.
谢谢!
解决方法:
你可能需要更加思考一下线程安全的确切含义.考虑一下你是否编写了这段代码:
class SomeSharedData(object):
def __init__(self):
self.errors = 0
此代码与您发布的代码完全一样是线程安全的.在Python中为属性赋值是线程安全的:始终赋值;它可能会或可能不会被另一个线程分配的另一个值覆盖,但是你总是得到一个值或另一个值,而不是两者的混合.同样,访问该属性会为您提供当前值.
您的代码中断的地方就像您使用原始版本或简化版本所说的那样,如下所示:
shared.errors += 1
不是线程安全的,但这是让你的代码安全的重点,这些是你需要注意的事情,而不是简单的get / set.
回答评论中的问题:
Python中的简单赋值只是重新绑定一个名称(不是复制)并保证原子;你得到一个值或另一个.但是,可以覆盖属性(或下标变量),就像在上面的属性中一样.在这种情况下,属性赋值可能会中断.所以答案是属性赋值通常是安全的,但如果它已经被属性或setattr或类似的覆盖,则不会.
此外,如果要替换的旧值是带有析构函数的Python类,或者包含带有析构函数的Python类的东西,那么析构函数代码可以在赋值的中间运行. Python仍然会确保它自己的数据结构不会被破坏(所以你永远不会得到段错误),但它不会为你自己做同样的事情.对此明显的解决方法是永远不要在任何类上定义del.
内容总结
以上是互联网集市为您收集整理的线程安全的Python属性/属性?全部内容,希望文章能够帮你解决线程安全的Python属性/属性?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。