from multiprocessing import Process
import time
# 任务
def task():
print('start...')
time.sleep(2)
print('end...')
if __name__ == '__main__':
p = Process(target=task)
# 告诉操作系统帮你开启子进程
p.start()
# p.join()
time.sleep(3)
# 主进程结束
print('主进程结束...')
通俗说法:类似于古代的君王和服侍君王的太监、妃子等,只要君王死了,其他人都得陪葬
注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止
import time
from multiprocessing import Process
def demo(name):
print(f'start...{name}')
time.sleep(100)
print(f'end...{name}')
print('子进程结束了...')
if __name__ == '__main__':
p = Process(target=demo, args=('童子军高留柱1号',))
# 守护进程必须在p.start()调用之前设置
p.daemon = True # 将子进程p设置为守护进程
p.start() # 告诉操作系统帮你开启子进程
time.sleep(1)
print('皇帝驾崩了...')
进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术
这个技术是为了避免进程A写入进程B的情况发生。进程的隔离实现,使用了虚拟地址空间。进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B
进程隔离的安全性通过禁止进程间内存的访问可以方便实现
# 代码验证进程间数据隔离
from multiprocessing import Process
n = 100
def work():
global n
n = 0
print('子进程内:',n)
if __name__ == '__main__':
p = Process(target=work)
p.start()
print('主进程内:',n)
主进程内: 100
子进程内: 0
进程同步(multiprocess.Lock)
锁——multiprocess.Lock
进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理
# 文件的内容为:{"count":1}
# 注意一定要用双引号,不然json文件无法识别
from multiprocessing import Process,Lock
import time, json, random
def search():
dic = json.load(open('db.json'))
print(f'\033[43m剩余票数{dic["count"]}\033')
def get():
dic = json.load(open('db.json'))
time.sleep(0.1) # 模拟读数据的网络延迟
if dic['count'] > 0:
dic['count'] -= 1
time.sleep(0.2) # 模拟写数据的网络延迟
json.dump(dic, open('db.json','w'))
print('\033[43m购票成功\033[0m')
def task():
search()
get()
if __name__ == '__main__':
for i in range(10): # 模拟并发100个客户端抢票
p = Process(target=task)
p.start()
# 引发问题:数据写入错乱
# 例子一
from multiprocessing import Process,Lock
import time, json, random
def search():
dic = json.load(open('db.json'))
print(f'\033[43m剩余票数{dic["count"]}\033[0m')
def get():
dic = json.load(open('db.json'))
time.sleep(random.random()) # 模拟读取数据网络延迟
if dic['count'] > 0:
dic['count'] -= 1
time.sleep(random.random()) # 模拟写数据的网络延迟
json.dump(dic, open('db.json', 'w'))
print('\033[32m购票成功\033[0m')
else:
print('\033[31m购票失败\033[0m')
def task(lock):
search()
lock.acquire() # 将买票这一环节由并发变成了串行,牺牲了运行效率,但保证了数据的安全性
get()
lock.release()
if __name__ == '__main__':
lock = Lock()
for i in range(10):
p = Process(target=task, args=(lock,))
p.start()
# 例子二
from multiprocessing import Process, Lock
import random, time, json
# 查看余票
def search(name):
# 1.读取db.json文件中的数据
with open('db.json', 'r', encoding='utf-8')as f:
db_dic = json.load(f)
print(f'用户{name}查看余票还剩{db_dic.get("count")}')
# 2.若有余票,购买成功,票数会减少
def buy(name):
with open('db.json', 'r', encoding='utf-8')as f:
db_dic = json.load(f)
# 进入这一步说明最先抢到票
if db_dic.get('count') > 0:
db_dic['count'] -= 1
time.sleep(random.random())
with open('db.json', 'w', encoding='utf-8')as f:
json.dump(db_dic, f)
print(f'\033[32m用户{name}抢票成功\033[0m')
else:
print(f'\033[31m用户{name}抢票失败\033[0m')
def run(name, lock):
search(name)
lock.acquire() # 加锁
buy(name)
lock.release() # 释放锁
if __name__ == '__main__':
lock = Lock()
# 开启多进程:实现并发
for line in range(10):
p_obj = Process(target=run, args=(f'sean{line}', lock))
p_obj.start()
总结:加锁可以保证多个进程修改用一块数据时,同一时间只有一个任务可以进行修改,即串行的修改,速度是慢了,但牺牲了速度却保证了数据安全。
原文:https://www.cnblogs.com/YGZICO/p/12006729.html