py并发_进程同步简述笔记

数据同步

在整个的操作系统之中每一个进程都有自己独立的数据存储单元,也就是说不同进程之间是无法直接实现数据共享的,后来依靠了管道流以及Mananger类来实现了进程之间的数据共享,那么就相当于打通了不同进程之间的限制,但是这样一来那么就会出现另外一种需求:不同的进程在操作同一个资源(或者说是某几个资源)的时候就必须去考虑到数据同步的问题了。

进程不同步所带来的问题

如果要想清楚同步的概念,那么首先一定要清楚为什么需要同步,那么既然是多个进程共享同一个资源,下面可以通过一个最为基础的售票程序来说明问题。

售票程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# coding: UTF-8
import multiprocessing,time # 导入多进程开发模块
def worker(dict): # 进程的处理函数
while True: #持续售票
number = dict.get("ticket") # 获取当前的票数
if number > 0: # 如果现在还有剩余票
time.sleep(1) # 判断和售票之间追加延迟
number -= 1 # 让票数减1
print("[%s] ticket = %s" % (multiprocessing.current_process().name,number)) # 输出提示信息
dict.update({"ticket":number}) # 更新票数
else: # 已经没有票了
break # 退出当前的售票循环
def main(): # 主函数
manager = multiprocessing.Manager() # 创建共享数据对象
# 此时创建了一个可以被多个进程之间共享的字典对象
mgr_dict = manager.dict(ticket=5) #默认提供有5张票
# 如果要进行售票肯定要同时准备多个进程于是下面创建10个售票进程列表
job_process = [multiprocessing.Process(target=worker,
name=("售票员 - %s" % item),
args=(mgr_dict,))
for item in range(3)] # 创建进程列表
for process in job_process:
process.start() # 启动售票进程
for process in job_process:
process.join()
print("[%s]所有进程执行完毕,最终剩余票数:%s" % (multiprocessing.current_process().name,mgr_dict.get("ticket")))
if __name__ == "__main__":
main()

[售票员 - 1] ticket = 4
[售票员 - 0] ticket = 4
[售票员 - 2] ticket = 4
[售票员 - 1] ticket = 3
[售票员 - 0] ticket = 3
[售票员 - 2] ticket = 3
[售票员 - 0] ticket = 2
[售票员 - 1] ticket = 2
[售票员 - 2] ticket = 2
[售票员 - 0] ticket = 1
[售票员 - 1] ticket = 1
[售票员 - 2] ticket = 1
[售票员 - 0] ticket = 0[售票员 - 1] ticket = 0

[售票员 - 2] ticket = 0
[MainProcess]所有进程执行完毕,最终剩余票数:0

进程已结束,退出代码0

注:由于在余票判断和售票以及更新票数之间无论怎样都会存在时间延迟,而且各个进程之间的各个步骤都是平等的,由操作系统决定如何执行,所以三个步骤是可分的,并且多个进程的各个步骤相互交叉,变得不可控,一个进程判断可以售票,所以去售第五张票,由于还未更新数据,其它进程也都进入了售第五张票的状态,所以一张票被卖了好几次,如上,客户肯定不买这样的帐。。

同步问题引出

所有的进程都是并发执行的,所以对于一些核心数据的控制就不可能直接的给出具体的操作,例如:本次的票数获取,票数判断以及票数的修改就是一套具体的操作,但是这套操作由于没有追加上同步的限制,所以就造成了不同步的问题。


py并发_进程同步简述笔记
https://blog.wangxk.cc/2020/02/01/py并发-进程同步简述笔记/
作者
Mike
发布于
2020年2月1日
许可协议