守护进程

内容概要

  • 同步异步阻塞非阻塞
  • 创建进程的两种方式
  • 进程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()








posted @ 2022-11-18 21:24  可否  阅读(20)  评论(0)    收藏  举报