1、多线程
当有多个线程,并且在这个几个线程中都会去调用deposit,就有可能同时操作这个bank对象,就有可能出一个线程覆盖另外一个线程的结果的问题。这时,可以使用 threading库里面的锁对象 Lock 去保护。
from threading import Thread,Lock
from time import sleep
bank = {
'byhy' : 0
}
bankLock = Lock()
# 定义一个函数,作为新线程执行的入口函数
def deposit(theadidx,amount):
# 操作共享数据前,申请获取锁
bankLock.acquire()
balance = bank['byhy']
# 执行一些任务,耗费了0.1秒
sleep(0.1)
bank['byhy'] = balance + amount
print(f'子线程 {theadidx} 结束')
# 操作完共享数据后,申请释放锁
bankLock.release()
theadlist = []
for idx in range(10):
thread = Thread(target = deposit,
args = (idx,1)
)
thread.start()
# 把线程对象都存储到 threadlist中
theadlist.append(thread)
for thread in theadlist:
thread.join()
print('主线程结束')
print(f'最后我们的账号余额为 {bank["byhy"]}')
运行结果:
子线程 0 结束
子线程 1 结束
子线程 2 结束
子线程 3 结束
子线程 4 结束
子线程 5 结束
子线程 6 结束
子线程 7 结束
子线程 8 结束
子线程 9 结束
主线程结束
最后我们的账号余额为 10
2、多进程
Python 官方解释器的每个线程要获得执行权限,必须获取一个叫 GIL(全局解释器锁)的东西。这就导致了 Python 的多个线程其实并不能同时使用多个CPU核心。所以如果是计算密集型的任务,不能采用多线程的方式,而要采用多进程的方式。
from multiprocessing import Process,Manager
from time import sleep
def f(taskno,return_dict):
sleep(2)
# 存放计算结果到共享对象中
return_dict[taskno] = taskno
if __name__ == '__main__':
manager = Manager()
# 创建 类似字典的 跨进程 共享对象
return_dict = manager.dict()
plist = []
for i in range(10):
p = Process(target=f, args=(i,return_dict))
p.start()
plist.append(p)
for p in plist:
p.join()
print('get result:')
# 从共享对象中取出其他进程的计算结果
for k,v in return_dict.items():
print (k,v)
运行结果:
get result:
0 0
2 2
3 3
1 1
4 4
9 9
5 5
7 7
6 6
8 8