创建进程的多种方式
1.通过鼠标栓剂程序
2.通过代码创建进程(掌握两种)
创建进程的代码在不同的操作系统下,底层原理是有区别的
在windos中创建进程类似于导入模块,使用启动脚本if __name__ == '__main__':
在linux和mac中创建进程类似于拷贝,不需要脚本启动,也可以使用脚本启动
第一种:
from multiprocessing import Process
import time
def task(name):
print(f'{name}运行开始')
time.sleep(3)
print(f'{name}运行结束')
if __name__ == '__main__':
p = Process(target=task,args=('hanser',))
p.start()
print('主进程')
第二种:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(f'{self.name}运行开始')
time.sleep(3)
print(f'{self.name}运行结束')
if __name__ == '__main__':
obj = MyProcess('tom')
obj.start()
print('主进程')
join方法
- 如何让主程序在子程序运行结束后在执行?
from multiprocessing import Process
import time
def task(name,n):
print(f'{name}正在运行')
time.sleep(n)
print(f'{name}运行结束')
if __name__ == '__main__':
p1 = Process(target=task,args=('hanser', 1))
p2 = Process(target=task, args=('tom', 2))
p3 = Process(target=task, args=('kunkun', 3))
start_time = time.time()
p1.start()
p2.start()
p3.start()
p1.join()
p2.join()
p3.join()
end_time = time.time() - start_time
print('总耗时:%s' % end_time)
print('主进程')
进程间的数据默认隔离
- 多个进程数据之间彼此之间是默认互相隔离的
对多个进程的数据进行交互需要借助'管道'或者'队列'
from multiprocessing import Process
num = 19800
def task():
global num
num = 200
print('子进程打印的num',num)
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print('父进程打印的num',num)
进出间通信(IPC机制)、
队列: 先进先出
from multiprocessing import Queue
q = Queue(3)
q.put(111)
print(q.full())
q.put(222)
q.put(333)
print(q.full())
q.put(444)
print(q.get_nowait())
print(q.get_nowait())
print(q.get_nowait())
print(q.get_nowait())
print(q.get())
print(q.empty())
"""
q.full()
q.empty()
q.get_nowait()
上述方法在多进程下不能准确使用(失效)!!!
"""
- IPC机制
- 1.主进程与子进程通信
from multiprocessing import Queue, Process
def procedure(q):
print('来自子进程procedure的方法往队里中添加了数据',q.get())
if __name__ == '__main__':
q = Queue()
q.put('主进程代码往队列里添加了的数据')
p = Process(target=procedure, args=(q,))
p.start()
p.join()
print('主进程')
- 2.子进程与子进程通信
from multiprocessing import Queue, Process
def procedure(q):
q.put('子进程procedure往队里中添加了数据')
def consumer(q):
print('子进程的consumer从队列中获取数据', q.get())
if __name__ == '__main__':
q = Queue() # 在主进程中产生q对象 确保所有的子进程使用的是相同的q
p1 = Process(target=procedure, args=(q,))
p2 = Process(target=consumer, args=(q,))
p1.start()
p2.start()
print('主进程')
生产者消费者模型
进程相关方法
from multiprocessing import current_process
import os
current_process().pid
os.getpid()
os.getppid
.terminate()
.is_alive()
守护进程
- 伴随着守护对象的存活或存活,死亡而死亡
from multiprocessing import Process
import time
def task(name):
print('守卫:%s存活' % name)
time.sleep(3)
print('守卫:%s被刀' % name)
if __name__ == '__main__':
p = Process(target=task, args=('1',))
p.daemon = True
p.start()
print('预言家被刀出局!!!')
互斥锁
- 日常12306买票流程是
1.查票
2.买票 >>>: 1.查票 2.买票
1.先创建一个json问价,设置一个字典模拟一下票的余量
2.创建py文件夹编写代码
from multiprocessing import Process
import time
import json
import random
def search(name):
with open(r'data.json', 'r', encoding='utf8') as f:
data = json.load(f)
print('%s在查票 当前余票为:%s' % (name, data.get('ticket_num')))
def buy(name):
with open(r'data.json', 'r', encoding='utf8') as f:
data = json.load(f)
time.sleep(random.randint(1, 3))
if data.get('ticket_num') > 0:
data['ticket_num'] -= 1
with open(r'data.json', 'w', encoding='utf8') as f:
json.dump(data, f)
print('%s买票成功' % name)
else:
print('%s很倒霉 没有抢到票' % name)
def run(name):
search(name)
buy(name)
if __name__ == '__main__':
for i in range(10):
p = Process(target=run, args=('用户%s'%i, ))
p.start()
僵尸进程和孤儿进程
- 僵尸进程
- 孤儿进程
- 父进程意外死亡 子进程正常运行 该子进程就称之为孤儿进程
- 孤儿进程也不是没有人管 操作系统会自动分配福利院接收