range(5,0,-2)
的意思是,从5开始,每次-2,大于0
第一次5
第二次3
第三次1
第四次-1不满足,不循环
所以3次
多线程用起来挺爽的,就是一不小心就可能会出现并发问题。比如:两个小孩争抢同一个糖果,两个线程对同一个共享资源进行访问。举个栗子吧!现在某个账户中有2000块钱。甲乙丙(三个线程)同时从该账户中取钱,每个人线程分别取800块。按照期望的总有一个线程取钱失败。因为账户的余额不能为负数。但是在并发情况下极有可能三个人都取钱成功,最终的账户余额为负数。
import threading
class Account:
# 定义构造函数
def __init__(self, account_no, balance):
"""
:param account_no: 账户
:param balance: 余额
"""
self.account_no = account_no
self._balance = balance
def draw(self, draw_amount):
"""
:param draw_amount: 需要取的钱
:return:
"""
if self._balance > draw_amount:
print(threading.current_thread().getName() + '从' + self.account_no + " 取钱成功,账户取出金额是:" + str(
draw_amount) + "\n")
self._balance = self._balance - draw_amount
print('账户余额是', self._balance)
else:
print(threading.current_thread().getName() + '从' + self.account_no + " 取钱失败\n")
# 两个线程并发取钱
account = Account('账户一', 2000)
threading.Thread(target=account.draw, name='线程一', args=(800,)).start()
threading.Thread(target=account.draw, name='线程二', args=(800,)).start()
threading.Thread(target=account.draw, name='线程三', args=(800,)).start()
极有可能出现如下运行结果:
线程一从账户一 取钱成功,账户取出金额是:800
线程二从账户一 取钱成功,账户取出金额是:800
账户余额是 1200
线程三从账户一 取钱成功,账户取出金额是:800
账户余额是 400
账户余额是 -400
这就是对共享资源不加控制引发的线程安全问题。线程安全问题出现一般有如下两种情况:
self._balance = self._balance - draw_amount
这个语句并不是一个原子的CPU执行命令。这个语句的执行共有三条CPU命令,分别是:self._balance
的值从内存加载到CPU的寄存器中。self._balance - draw_amount
操作。