存钱
1. 存钱
存钱的关键代码:
def deposit(amount):
balance = get_balance(account, ...)
balance += amount
write_balance(account, balance)
考虑有两个操作,
- ATM存钱
- 在线转账
1.1 测试用例
import threading
import random
import sys
balance = 0
def deposit(list_amount):
global balance
for amount in list_amount:
balance += amount
def main():
# Generate random numbers
if len(sys.argv) != 2:
print('The usage: python {} num'.format(sys.argv[0]))
exit()
times = int(sys.argv[1])
# list_deposit_amount1 = [random.randint(1, 101) for _ in range(times)]
list_deposit_amount1 = [1] * times
list_deposit_amount2 = [1] * times
print('-----At the beginning-----')
print('Initial balance: {}'.format(balance))
print('The total amount of deposit1: {}'.format(sum(list_deposit_amount1)))
print('The total amount of deposit2: {}'.format(sum(list_deposit_amount2)))
expected_balance = balance + sum(list_deposit_amount1) + sum(list_deposit_amount2)
print('The expected balance: {}'.format(expected_balance))
# Multiple threads
deposit_thread1 = threading.Thread(target=deposit, args=(list_deposit_amount1,))
deposit_thread2 = threading.Thread(target=deposit, args=(list_deposit_amount2,))
deposit_thread1.start()
deposit_thread2.start()
deposit_thread1.join() # Waits until the first thread is finished.
deposit_thread2.join()
print('\n-----In the end-----')
print('The balance: {}'.format(balance))
if __name__ == '__main__':
main()
1.2 测试结果
累计存钱次数少:
$ python .\deposit_money.py 1000
-----At the beginning-----
Initial balance: 0
The total amount of deposit1: 1000
The total amount of deposit2: 1000
The expected balance: 2000
-----In the end-----
The balance: 2000
加大存钱次数:
1.3 分析原因
balance --> R
R <-- R + amount
R --> balance
2. 修改后
2.1 加锁
2.2 测试用例
import threading
import random
import sys
balance = 0
mutex = threading.Lock()
def deposit(list_amount):
global balance
for amount in list_amount:
mutex.acquire()
balance += amount
mutex.release()
def main():
# Generate random numbers
if len(sys.argv) != 2:
print('The usage: python {} num'.format(sys.argv[0]))
exit()
times = int(sys.argv[1])
# list_deposit_amount1 = [random.randint(1, 101) for _ in range(times)]
list_deposit_amount1 = [1] * times
list_deposit_amount2 = [1] * times
print('-----At the beginning-----')
print('Initial balance: {}'.format(balance))
print('The total amount of deposit1: {}'.format(sum(list_deposit_amount1)))
print('The total amount of deposit2: {}'.format(sum(list_deposit_amount2)))
expected_balance = balance + sum(list_deposit_amount1) + sum(list_deposit_amount2)
print('The expected balance: {}'.format(expected_balance))
# Multiple threads
deposit_thread1 = threading.Thread(target=deposit, args=(list_deposit_amount1,))
deposit_thread2 = threading.Thread(target=deposit, args=(list_deposit_amount2,))
deposit_thread1.start()
deposit_thread2.start()
deposit_thread1.join() # Waits until the first thread is finished.
deposit_thread2.join()
print('\n-----In the end-----')
print('The balance: {}'.format(balance))
if __name__ == '__main__':
main()
def withdraw(list_amount):
global balance
for amount in list_amount:
if balance >= amount:
balance -= amount