35 进程

进程

课程回顾:
编程语言的发展:
机器语言 : 二进制
汇编语言 : 指令,命令形式的
高级语言 : 面向过程(C) 面对对象(python)
操作系统的目标:
为了用户更方便的使用
并行:指两件或多件事情,在同一时间点同时执行
并发:指两件或多件事情,在同一时间间隔内同时执行
计算机组成:
CPU,主板,存储,输入,输出

进程由三部分组成:
代码段,数据段,PCB(进程控制块)
进程的三个基本状态:
就绪状态:获得了除CPU之外运行需要的所有资源
执行状态:获得了所有资源,处于正在执行的状态
阻塞状态:因为各种原因,导致进程放弃了cpu,导致进程无法继续执行,此时进程处于内存

dos系统: 单用户单任务
windows系统: 单用户多任务(早期的windows)
unix系统: 多用户多任务

为什么要有操作系统?
1 封装了所有硬件的接口,使用户更方便的使用
2 对于计算机内所有资源,进行一个合理的调度和分配


多进程的模块:
multiprocessing
Process

今天的任务:
1 如何开启多进程及多进程相关常用方法
并行:
并发:
早期单核cpu时候,没有并行的概念,只有并发(微观上串行,宏观上并行)
同步
异步
阻塞
非阻塞

from multiprocessing import Process

获取当前进程的pid号,os.getpid()
获取当前进程的父进程的pid号,os.getppid()
def func(i):
    time.sleep(1)
    print('这里是儿子进程,儿子自己的pid是%s,儿子的父进程的pid是%s'%(os.getpid(),os.getppid()))

# os.getpid()获取的是当前进程自己的pid
# os.getppid()获取的是当前进程的父进程的pid
if __name__ == '__main__':
    p = Process(target=func,args=(1,))# 实例化一个进程对象
    p.start()# 开启一个子进程
    print('这里是父亲进程,父进程自己的pid是:%s,父亲的父亲的pid是%s'%(os.getpid(),os.getppid()))
获取pid


开启子进程的方式:
1 p = Process(target=func,args=(,))
target: 是子进程要执行的任务
args:是父进程给子进程传递的参数
2 自定义类,去继承Process

进程的方法:
p.start()开启子进程,底层调用的是p.run()
class MyProcess(Process):
    def __init__(self):
        super(MyProcess, self).__init__()
    def run(self):
        print('这是以继承类的方式开启的子进程')

if __name__ == '__main__':
    p1 = MyProcess()
    # p1.start()# 是指,解释器告诉操作系统,去帮我开启一个进程,   就绪状态
    p1.run()# 告诉操作系统,现在马上帮我执行这个子进程           执行
继承的类的形式开启进程

今日总结:
1 名词解释
并行
并发
同步
异步
阻塞
非阻塞

2 进程的两种开启方法
(1) p = Process(target=None,args(,))
(2) 自定义类,继承Process父类

3 进程的常用方法
(1) start() 开启一个子进程
(2) join() 异步变同步(就是让父进程停留在join这句话,等待子进程执行结束,父进程再继续执行)
(3) is_alive() 判断进程是否活着
(4) terminate() 杀死进程
4 进程的常用属性
(1) p.name = 给p进程一个名字
(2) p.pid 返回p进程的pid
(3) p.daemon = True 将p进程设置为守护进程。(True为守护进程,False为普通进程)
守护进程的两个特点:
守护进程会随着父进程的结束而结束
守护进程不能再创建子进程(不能要孩子)
class MyProcess(Process):
    def __init__(self):
        super(MyProcess, self).__init__()#  执行父类的__init__方法
        # self.name = name

    def run(self):
        print('这是以继承类的方式开启的子进程,他的名字是%s'% self.name)

if __name__ == '__main__':
    p1 = MyProcess()
    p1.start()# 是指,解释器告诉操作系统,去帮我开启一个进程,   就绪状态
    # p1.run()# 告诉操作系统,现在马上帮我执行这个子进程           执行
获取name
from multiprocessing import Process
import time


def func():
    time.sleep(1)
    print(123)


if __name__ == '__main__':
    p = Process(target=func,)
    p.start()
    p.terminate()# 杀死p进程,让解释器告诉操作系统,请杀掉p进程。
    print('子进程是否还活着?', p.is_alive())
    time.sleep(0.002)
    print('子进程是否还活着?', p.is_alive())
    # 返回一个bool值,如果返回True,代表进程还活着,如果返回False,代表子进程死了

# p.is_alive() 判断p进程是否还活着
# p.terminate() 杀死p进程
进程的杀死
from multiprocessing import Process
import time

def func():
    for i in range(500):
        time.sleep(0.01)
        print('儿子在这里')

if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    p.join()# 是让主进程等待子进程执行完。  现象:主进程执行到这句话,主进程阻塞住,等待子进程执行
    # time.sleep(1)
    for i in range(100):
        time.sleep(0.01)
        print('爸爸在这里')

# 开启一个正常的子进程,父进程会等待子进程结束后,父进程也就是程序才结束
# p.join()# 是让主进程等待子进程执行完。  现象:主进程执行到这句话,主进程阻塞住,等待子进程执行
# 如何把父进程和子进程之间的关系变为同步或者异步?
# 父进程执行join,就会变成同步,不执行join,父进程和子进程就是异步的关系
# join必须放在start()后边
start与join
from multiprocessing import Process
import time
import os

def func():
    print('这里是儿子,儿子的pid是%s'%(os.getpid()))

if __name__ == '__main__':
    p = Process(target=func)
    p.start()
    p.name = 'alex'
    print('儿子的名字是%s'%p.name)
    print('儿子的pid是%s'%p.pid)
    print('儿子是不是守护进程?',p.daemon)
常用属性
from multiprocessing import Process
import time

def func():
    time.sleep(100)
    print('这里是儿子哦')

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True  # 将p进程设置为守护进程,必须要在start之前设置
    p.start()
    time.sleep(1)
    print('这是爸爸')
# 总结一下:
#     守护进程:跟随着父进程的代码执行结束,守护进程就结束
守护进程
from multiprocessing import Process
import time

def func1():
    print('这里是孙子')

def func():
    p = Process(target=func1)
    p.start()
    time.sleep(5)
    print('这里是儿子哦')

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True     # 将p进程设置为守护进程,必须要在start之前设置
    p.start()
    time.sleep(1)
    print('这是爸爸')
    # 守护进程:不允许开启子进程
守护进程的特点
from multiprocessing import Process
import time


def func():
    for i in range(10):
        time.sleep(1)
        print(time.strftime('%H:%M:%S'))

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True # 将p进程设置为守护进程,必须要在start之前设置
    p.start()
    time.sleep(5)
    print('这是爸爸')
守护进程的用法


2 多进程编程,数据不安全的问题



代码演示:
from multiprocessing import Process
import time
import random

def func(i):
    print('我是%s'%i)


if __name__ == '__main__':
    l = []
    addr = ['河南的','山东的','辽宁的','湖南的']
    for i in addr:
        p = Process(target=func,args=(i,))
        p.start()
        # p.join()
        l.append(p)
    [p.join() for p in l]   # 列表推导式
    time.sleep(1)
    print('我选%s' % (random.choice(addr)))
多个子进程
原文地址:https://www.cnblogs.com/zhuangdd/p/12750563.html