创建进程的多种方式

需要掌握的两种

方式一、
from multiprocessing import Process
import time


def task(name):
    print(f'{name}正在运行')
    time.sleep(2)
    print(f'{name}运行结束')


if __name__ == '__main__':
    p = Process(target=task,args=('joker',))
    p.start()
    print('主进程')

创建进程的代码在不同的操作系统中 底层原理有区别

在Windows中 创建进程类似于导入模块

   if __name__ == '__main__':启动脚本

在mac、linux中 创建进程类似于直接拷贝 不需要启动脚本 但是为了兼容性 也可以使用

方式二、
class MyProcess(Process):
    def __init__(self, name):
        super().__init__()  # 重写父类方法
        self.name = name

    def run(self):
        print(f'{self.name}正在运行')
        time.sleep(2)
        print(f'{self.name}运行结束')


if __name__ == '__main__':
    obj = MyProcess('joker')
    obj.start()
    print('主')

join方法

from multiprocessing import Process
import time


def task(name):
    print(f'{name}正在运行')
    time.sleep(2)
    print(f'{name}运行结束')


if __name__ == '__main__':
    p = Process(target=task,args=('joker',))
    p.start()
    p.join()  # 等待子进程运行完在运行主进程
    print('主进程')

进程间数据默认隔离

from multiprocessing import Process

money = 100


def task():
    global money
    money = 666
    print('子进程money', money)  # 子进程money 666


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()
    print('父进程money', money)  # 父进程money 100

进程间通信(IPC机制)

消息队列

  队列:先进先出

  堆栈:先进后出

from multiprocessing import Queue

# 创建队列对象
q = Queue(5)  # 可以自定义队列长度

# 往队列添加数据
q.put(111)
q.put(222)
q.put(333)
# print(q.full())  # False 判断队列是否已经存满
q.put(444)
q.put(555)
# print(q.full())  # Ture
q.put(666)  # 超出数据存放极限 那么程序一致处于阻塞态 直到队列中有数据被取出
print(q.get_nowait())  # 队列中如果没有数据可取 直接报错
print(q.get())  # 超出数据获取极限 那么程序一致处于阻塞态 直到队列中有数据被添加
print(q.empty())  # 判断队列是否已经空了

"""
  q.full()
  q.empty()
  q.get_nowait()
上述方法在多进程下不能准确使用(失效)!!!
正确
"""

IPC机制
  1.主进程与子进程通信
  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
1.查看进程号
	current_process().pid 
	os.getpid()   
	os.getppid() 
2.销毁子进程
	p1.terminate()
3.判断进程是否存活
	p1.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=('jason',))
    p.daemon = True  # 将子进程设置为守护进程:主进程代码结束 子进程立刻结束 必须要在start前面加
    p.start()
    print('主进程!!!')

僵尸进程与孤儿进程、

僵尸进程
  • 进程已经运行结束 但是相关的资源并没有完全清除
  • 需要父进程参与回收
孤儿进程
  • 父进程意外死亡 子进程正常运行 该字进程就称之为孤儿进程
  • 孤儿进程也不是没有人管 操作系统会自动分配福利院接收
 posted on 2022-08-09 17:24  Joker_Ly  阅读(145)  评论(0)    收藏  举报