Python VM 内部会使用 global interpreter lock (GIL)来确保同一时间只有一个线程运行。通常 Python 只会在字节码指令之间切换线程;切换的频率可以通过设置 sys.setswitchinterval()
指定。从 Python 程序的角度来看,每一条字节码指令以及每一条指令对应的 C 代码实现都是原子的。
理论上说,具体的结果要看具体的 PVM 字节码实现对指令的解释。而实际上,对内建类型(int,list,dict 等)的共享变量的“类原子”操作都是原子的。
举例来说,下面的操作是原子的(L、L1、L2 是列表,D、D1、D2 是字典,x、y 是对象,i,j 是 int 变量):
<span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">L1</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">L2</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">L</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">L1</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">L2</span>
<span class="n">L</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">y</span>
<span class="n">x</span><span class="o">.</span><span class="n">field</span> <span class="o">=</span> <span class="n">y</span>
<span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">y</span>
<span class="n">D1</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D2</span><span class="p">)</span>
<span class="n">D</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
www#gaodaima.com来源gaodai$ma#com搞$$代**码网搞代码
这些不是原子的:
<span class="n">i</span> <span class="o">=</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span>
<span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">L</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
<span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
覆盖其他对象的操作会在其他对象的引用计数变成 0 时触发其 __del__()
方法,这可能会产生一些影响。对字典和列表进行大量操作时尤其如此。如果有疑问的话,使用互斥锁!
来源:搞代码网:原文地址:https://www.gaodaima.com