守护进程
内容概要
- 同步异步阻塞非阻塞
- 创建进程的两种方式
- 进程join方法
- 进程之间通信之IPC机制
- 生产者于消费者模型
- 互斥锁
同步与异步
-
同步
就是当调用一个函数的时候,等到函数执行完才会往下执行。
-
异步
就是在调用一个函数的时候,不会等到函数执行完,就是调用一下,然后就去执行下面的函数了
阻塞与非阻塞
用来标识任务的执行状态(线程)
-
阻塞
就是阻塞态
-
非阻塞
就是 就绪态 或者 运行态
代码创建进程的两种方式
# 方式一
# from multiprocessing import Process
#
# def task():
# print("进程 哈啊")
#
#
# if __name__ == '__main__':
# p1 = Process(target=task)
# p1.start() # 创建 并启动进程
# print("主")
# 传值
# from multiprocessing import Process
#
# def task(name):
# print("进程 哈啊 %s" % name)
#
#
# if __name__ == '__main__':
# p1 = Process(target=task, args=("jason", ))
# p1.start() # 进程 哈啊 jason
# print("主")
"""
args 一定要写 元组形式 位置传参
kwargs 要写字典形式 关键字传参
"""
# 方式二
# from multiprocessing import Process
#
#
# class MyProcess(Process):
# def run(self):
# print("哈哈哈,第二种方法创建进程哦")
#
# if __name__ == '__main__':
#
# p = MyProcess()
# p.start()
# print("主")
from multiprocessing import Process
class MyProcess(Process):
def __init__(self, name1):
self.name1 = name1
super().__init__()
def run(self):
print("哈哈哈,第二种方法创建进程哦", self.name)
print("哈哈哈,第二种方法创建进程哦", self.name1)
if __name__ == '__main__':
p = MyProcess("jason")
p.start() # 哈哈哈,第二种方法创建进程哦 MyProcess-1
# 哈哈哈,第二种方法创建进程哦 jason
print("主")
"""
有个默认的 name属性名 为进程名称
如果要设置有参的进程
得重写一下 __init__方法
如果要使用name属性 可以先写super方法 然后在更改name 属性名
"""
进程的join方法
join可以让主进程等子进程运行完在运行
from multiprocessing import Process
import time
def task():
print("进程 哈啊")
time.sleep(2)
print("呦呵")
if __name__ == '__main__':
p1 = Process(target=task)
p1.start() # 创建 并启动进程
# p1.join(1) # 参数就是主进程就等你 1 秒 1秒后运行主进程
p1.join() # 如果不写则会等子进程运行完在运行主进程
print("主")
from multiprocessing import Process
import time
def task():
print("进程 哈啊")
time.sleep(2)
print("呦呵")
if __name__ == '__main__':
p1 = Process(target=task)
p2 = Process(target=task)
p3 = Process(target=task)
start_time = time.time()
p1.start() # 创建 并启动进程
p2.start()
p3.start()
p1.join() # 如果不写则会等子进程运行完在运行主进程
p2.join()
p3.join()
print("主", time.time() - start_time) # 主 2.127305746078491
"""
运行的时间是 2.127305746078491
以为只要运行start 那么进程就会执行 而join让等 等你等呗 我的进程已经起来了
我就开始一起运行 让后等p1 p2 p3 他都开始一起运行了 运行的同一个运行的时间也
一样等一个跟等三个基本一样所以运行时间是 两秒多
"""
from multiprocessing import Process
import time
def task():
print("进程 哈啊")
time.sleep(2)
print("呦呵")
if __name__ == '__main__':
p1 = Process(target=task)
p2 = Process(target=task)
p3 = Process(target=task)
start_time = time.time()
p1.start() # 创建 并启动进程
p1.join()
p2.start()
p2.join()
p3.start()
p3.join() # 如果不写则会等子进程运行完在运行主进程
print("主", time.time() - start_time) # 主 6.264748811721802
"""
这是起一个 等一个 所以时间是 6.264748811721802
"""
进程之间通信之IPC机制
同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)
进程之间通信: IPC
消息队列:存储数据的地方 所有人都可以存 也都可以取
"""
消息队列
"""
from multiprocessing import Process
from multiprocessing import Queue
q = Queue(3) # 产生一个消息队列 里面的参数是可以限制里面有 就是建一个里面可以存三个数据的消息队列
q.put("jason") # 放数据
q.put("oscar")
q.put("kevin")
q.put("kk") # 因为只能放三个 所以第四个一直阻塞住
print(q)
from multiprocessing import Process
from multiprocessing import Queue
q = Queue(3) # 产生一个消息队列 里面的参数是可以限制里面有 就是建一个里面可以存三个数据的消息队列
q.put("jason") # 放数据
q.put("oscar")
q.put("kevin")
# print(q)
# print(type(q))
print(q.get())
print(q.get())
print(q.get())
"""
消息队列 所以是先进先出
"""
from multiprocessing import Process
from multiprocessing import Queue
def add_q(q):
q.put("jason")
q.put("oscar")
q.put("kevin")
def get_q(q):
print(q.get())
print(q.get())
print(q.get())
if __name__ == '__main__':
q = Queue(3)
p1 = Process(target=add_q, args=(q,))
p2 = Process(target=get_q, args=(q,))
p1.start()
p2.start()
print("主")
生产者消费者模型
生产者
负责产生数据的' 人'
消费者
负责处理数据的'人'
该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以)
进程对象的多种方法
1.如何查看进程号
# 方式一
# from multiprocessing import Process
# from multiprocessing import current_process
#
#
#
# def task():
# print(current_process())
# print("我是子进程哦")
# print(current_process().pid)
#
#
# if __name__ == '__main__':
# p1 = Process(target=task, name="我是子哦")
# p1.start()
# print("主", current_process().pid)
#
# 方式二
import os
from multiprocessing import Process
def task():
print("我是子进程哦")
print("子进程的pid", os.getpid())
print("父进程的pid", os.getppid())
if __name__ == '__main__':
p1 = Process(target=task, name="我是子哦")
p1.start()
print("主", os.getpid())
# 方式三
import os
from multiprocessing import Process
def task():
print("我是子进程哦")
print(os.getpid())
if __name__ == '__main__':
p1 = Process(target=task, name="我是子哦")
p1.start()
print(p1.pid, "pp哦") # 获取的也是子进程的pid
print("主", os.getpid())
from multiprocessing import Process
def task():
print("我是子进程哦")
if __name__ == '__main__':
p = Process(target=task, name="我是子哦")
# p.start() # 启动进程,并调用子进程下的p.run()
p.run() # 跟start一样
p.terminate() # 强制终止进程p,不会进行任何清理操作
# 如果p创建了子进程,该子进程就成立僵尸进程,
# 使用该方法特别小心这种情况。如果p还保存了一个锁那么将也不会释放
# 进而导致死锁
p.is_alive() # 如果仍在运行则返回 True
p.start() # 启动进程,并调用子进程下的p.run()
p.run() # 跟start一样
p.terminate()
# 强制终止进程p,不会进行任何清理操作
# 如果p创建了子进程,该子进程就成立僵尸进程,
# 使用该方法特别小心这种情况。如果p还保存了一个锁那么将也不会释放进而导致死锁
p.is_alive() # 如果仍在运行则返回 True
守护进程
守护进程会随着守护的进程结束而立即结束
from multiprocessing import Process
import time
def task():
print("我活着")
time.sleep(5)
print("我个屁了")
if __name__ == '__main__':
p = Process(target=task)
p.daemon = True # 让p 成为主进程的守护进程(就是父进程的守护进程)
p.start()
time.sleep(1)
print("主")
僵尸进程和孤儿进程
-
僵尸进程
进程执行完毕后不会立刻销毁所有的数据 会有一些信息短暂保留下来
比如进程号、进程执行的时间、进程消耗功率等给父进程查看
ps:所有的进程都有编程僵尸进程的一段时间
-
孤儿进程
子进程正常运行 父进程意外死亡 操作系统针对孤儿进程会派遣福利院管理(win下init 端口号为 1)
多进程数据错乱问题
模拟抢票
from multiprocessing import Process, Lock
import time
import json
import random
def search(name):
with open("data.json", "r", encoding="utf8")as f:
data = json.load(f)
print("%s 正在查票 当前票余额为 %s" % (name, data.get("data")))
def buy(name,lock):
lock.acquire() # 上锁
with open("data.json", "r", encoding="utf8")as f:
data = json.load(f)
time.sleep(random.randint(1,4))
if data.get("data") > 0:
data["data"] = data.get("data") - 1
with open("data.json", "w", encoding="utf8")as f:
json.dump(data, f)
print("%s 抢票成功 " % name)
else:
print("%s 抢票失败" % name)
lock.release() # 释放锁
def run(i,lock):
search(i)
buy(i,lock)
if __name__ == '__main__':
lock = Lock()
for i in range(6):
p1 = Process(target=run, args=(i, lock))
p1.start()

浙公网安备 33010602011771号