内容简介:我们知道python的全局解释器锁(GIL)用于确保Python同一时刻只能有一条线程在执行(也就是其实Python中的多线程是假的,将其理解成协程似乎更加合理)。在Python多线程运行的情况下,全局解释器一般只在字节码之间进行线程切换,所以,我们在编写Python代码的时候,可以认为一条字节码的执行是“原子的”(字节码对应的C实现也被认为是“原子执行的”)。理解了上面的实现之后,我们知道,只要知道python代码对应的字节码是什么,我们就可以知道那些操作是“原子的”;但是实际上,我们不可能当“人肉解释器
我们知道 python 的全局解释器锁(GIL)用于确保Python同一时刻只能有一条线程在执行(也就是其实Python中的多线程是假的,将其理解成协程似乎更加合理)。在Python多线程运行的情况下,全局解释器一般只在字节码之间进行线程切换,所以,我们在编写Python代码的时候,可以认为一条字节码的执行是“原子的”(字节码对应的C实现也被认为是“原子执行的”)。
理解了上面的实现之后,我们知道,只要知道python代码对应的字节码是什么,我们就可以知道那些操作是“原子的”;但是实际上,我们不可能当“人肉解释器”。这里,我们只想知道我们常见的共享于python多线程的变量的哪些操作是“原子的”。对于buildin 数据类型(int,list,dict等)的简单操作通常是只用一条字节码就完成的,但是复杂的操作则不一定了。
例如对于内建类型,下面的操作是原子的(L、L1、L2是list,D、D1、D2是dict,x、y是object,i、j是int):
L.append(x) L1.extend(L2) x = L[i] x = L.pop() L1[i:j] = L2 L.sort() x = y x.field = y D[x] = y D1.update(D2) D.keys()
但是下面的例子则不是原子的:
i = i+1 L.append(L[-1]) L[i] = L[j] D[x] = D[x] + 1
通常,那些引起replace其他对象的操作,可能会触发对象的 __del__
方法,因此不是原子的。需要特别注意的是对list和dict的批量更新,这通常也不是原子的。
讲了这么多,其实有时很难区分对对象的哪些操作是 simple operation(对应于原子操作),哪些是 composite operations(对应于非原子操作)。所以《Google Python style guide》建议:
Do not rely on the atomicity of built-in types.
While Python’s built-in data types such as dictionaries appear to have atomic operations, there are corner cases where they aren’t atomic (e.g. if hash or eq are implemented as Python methods) and their atomicity should not be relied upon. Neither should you rely on atomic variable assignment (since this in turn depends on dictionaries).
我们不应该依赖CIL带来的原子性,当有thread-safe疑虑的时候,应该毫不犹豫就上锁。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
电子邮件营销密码
[美] Jeanniey Mullen、David Daniesl / 薛剑韬 / 人民邮电出版社 / 2009-9 / 39.00元
在当今互联网蓬勃发展的形势下,电子邮件是互联网应用最广的服务之一。那么如何利用其作为有效的营销工具呢?本书系统地讲解了美国电子邮件营销的预算统筹、营销策略、管理模式、执行机制、涉及的技术、营销实施的细节等,其方法有很强的可循性,并可预见将获得的成果。阅读本书之后,读者会深刻感受到电子邮件营销的博大精深,它既是一门扎实严谨的科学,又是一项充满创造力的艺术。. 本书适合企业管理人员及市场营销人员......一起来看看 《电子邮件营销密码》 这本书的介绍吧!