进程同步

进程同步工具
有先后顺序 就是同步
进程之间 就是一部
希望原本一部的多进程操作,维持一个顺序


lock = Lock() ## 创造了一把锁
lock.acquire() ##获取了这把锁的钥匙
lock.release() ## 归还这把锁的钥匙
当几个人进一间屋子,如果第一个人获取了锁的钥匙,那他进去后会带着钥匙进去 然后反锁,后面的人进不去
只有他把锁还了以后 下一个人才可以拿锁进去

当多个进程共享一段数据的时候,数据会出现不安全的现象,这就需要枷锁来维护数据的安全性
拿抢票的例子来说:
import json
import time
from multiprocessing import Lock
from multiprocessing import Process

def search(i):
with open('dp','r') as f:
count_dic = json.load(f)
time.sleep(0.2)
print('person %s 余票 : %s张'%(i,count_dic['count']))

def buy(i):
with open('dp','r') as f:
count_dic = json.load(f)
time.sleep(0.2)
if count_dic['count'] >0:
count_dic['count'] -=1
print('person %s 购票成功' %i)
time.sleep(0.2)
with open('dp','w') as f:
json.dump(count_dic,f)

def task(i,lock):
search(i)
lock.acquire() ##如果之前已经被acquire了 且 没有被release name进程会在这里阻塞
buy(i)
lock.release()

if __name__ =='__main__':
lock = Lock()
for i in range(10):
p = Process(target=task,args=(i,lock))
p.start()

信号量
from multiprocessing import Semaphore ##信号量
信号量的本质
多把钥匙对应一把锁
lock+count计数
拿ktv举个例子,有10个人 但是只有4个小房子 这样子怎么办呢?

import time
import random
from multiprocessing import Process,Semaphore
def ktv(i,sem):
sem.acquire()
print('person %s 进入了ktv' %i)
time.sleep(random.randint(1,4))
print('person %s 走出了ktv' %i )
sem.release()

if __name__ == '__main__':
sem = Semaphore(4)
for i in range(10):
p = Process(target=ktv,args=(i,sem))
p.start()

#事件
from multiprocessing import Event,Process

# wait() 方法 等待
# 阻塞 如果这个标志是False 那么就阻塞
# 非阻塞 如果这个标志是True 那么就非阻塞
# 查看标志 is_set()
# 修改标志 set() 将标志设置为True
# clear() 将标志设置为False

e = Event()
print(e.is_set()) ##在事件的创建之初, 默认是False
e.set() ##将标志设置为True
print(e.is_set())
e.wait() ## 相当于什么都没做 pass
e.clear() ##将标志设置为False
e.wait() ##永远阻塞
e.wait(timeout = 10) ##如果信号在阻塞10s之内变为True,那么不继续阻塞直接pass
##如果就阻塞10s之后状态还是没变,那么继续
print(e.is_set()) ##无论前面的wait的timeout是否通过,我的状态都不会因此改变

#红绿灯模型
#控制交通灯的进程
import time
import random
def traffic_light(e):
print('33[1;31m 红灯亮33[0m')
while True:
time.sleep(2)
if e.is_set():
print('33[1;31m 红灯亮33[0m')
e.clear()
else:
print('33[1;32m 绿灯亮33[0m')
e.set()

##车 等或者通过
def car(id,e):
if not e.is_set():
print('car %s 等待' % id)
e.wait()
print('car %s 通过' %id)

def police_car(id,e):
if not e.is_set():
e.wait(timeout=0.5)
print('police car %s 通过' %id)

##主进程 启动交通控制灯 启动车的进程
if __name__ == '__main__':
e = Event()
p = Process(target=traffic_light,args=(e,))
p.start()
car_lst = [car,police_car]
for i in range(20):
p = Process(target=random.choice(car_lst),args=(i,e))
p.start()
time.sleep(random.randrange(0,3,2))



总结
进城之间的数据是隔离的
进程御锦城之间是不能自由的交换内存数据的
全局的变量在子进程中修改 其他进程是感知不到的
守护进程
特点 生命周期只和主进程的代码有关系,和其他子进程没关系
用处 报活
多进程启动tcp协议的socket来完成并发
进程的同步控制---进程之间有一些简单的信号传递,但是用户不能感知,且用户不能传递自己想传递的内容

信号量
锁+计数器实现
事件 wait
原文地址:https://www.cnblogs.com/liuafan/p/9367967.html