Skip to main content
 首页 » 编程设计

python之程序行为的解释(Python)

2025年05月04日15小虾米

import threading 
 
shared_balance = 0 
 
class Deposit(threading.Thread): 
    def run(self): 
        for i in xrange(1000000): 
            global shared_balance 
            balance = shared_balance 
            balance += 100 
            shared_balance = balance 
 
class Withdraw(threading.Thread): 
    def run(self): 
        for i in xrange(1000000): 
            global shared_balance 
            balance = shared_balance 
            balance -= 100 
            shared_balance = balance 
 
thread1 = Deposit() 
thread2 = Withdraw() 
 
thread1.start() 
thread2.start() 
 
thread1.join() 
thread2.join() 
 
 
print shared_balance 

每次我运行这个程序时,它都会输出一个随机数。如果存入 100、100 万次,取款 100、100 万次,为什么输出不是 0?

请您参考如下方法:

您需要使用 threading.Lock安全地访问你的变量:

from threading import Thread, Lock 
 
shared_balance = 0 
 
class Deposit(Thread): 
    def __init__(self, lock): 
        super(Deposit, self).__init__() 
        self.lock = lock 
    def run(self): 
        global shared_balance 
        for i in xrange(1000000): 
            with self.lock: 
                shared_balance += 100 
 
class Withdraw(Thread): 
    def __init__(self, lock): 
        super(Withdraw, self).__init__() 
        self.lock = lock 
    def run(self): 
        global shared_balance 
        for i in xrange(1000000): 
            with self.lock: 
                shared_balance -= 100 
 
shared_lock = Lock() 
thread1 = Deposit(shared_lock) 
thread2 = Withdraw(shared_lock) 
 
thread1.start() 
thread2.start() 
 
thread1.join() 
thread2.join() 
 
print shared_balance 

输出:

>>> 0 

另外,看看为以下内容生成的字节码:

a = 0 
def f(): 
    global a 
    a += 10 

“a += 10”的字节码:

 6 LOAD_GLOBAL              0 (a)     # Load global "a"  UNSAFE ZONE 
 9 LOAD_CONST               2 (10)    # Load value "10"  UNSAFE ZONE 
12 INPLACE_ADD                        # Perform "+="     UNSAFE ZONE 
13 STORE_GLOBAL             0 (a)     # Store global "a"  
16 LOAD_CONST               0 (None)  # Load "None" 
19 RETURN_VALUE                       # Return "None"   

在 Python 中,字节码的执行不能被抢占。它使线程使用起来非常方便。但在那种情况下,执行“+=”操作需要执行 4 次字节码。这意味着任何其他线程的任何其他字节码都易于在这些字节码之间执行。这就是它不安全的原因,也是您应该使用锁的原因。