python语法基础-并发编程-进程-进程理论和进程的开启

##############################################

"""
并发编程的相关概念:

进程
1,运行中的程序,就是进程,程序是没有生命的实体,运行起来了就有生命了,
操作系统可以管理进程,进程是操作系统基本的执行单元,
2,每一个进程都有它自己的地址空间,进程之间是不会混的,比如qq不能访问微信的地址空间,
操作系统替你隔离开了,这也是操作系统引入进程这个概念的原因,

#######################################
进程的调度
1,先来先服务,有一个不好的,就是不利于短作业
2,短作业优先算法,但其对长作业不利;不能保证紧迫性作业(进程)被及时处理;作业的长短只是被估算出来的。
3,时间片轮转算法,就是轮流执行,已经很科学了,
4,多级反馈队列算法,有多个队列,有一个新任务来了放入第一个队列,这是优先级加上时间片轮转,第二个任务来了放入下一级,

#######################################
并发和并行:
进程的并行:这种只有在多核cpu才可以实现,
进程的并发:这是轮流执行,由于速度很快,看起来像是一起执行的,比如一遍听音乐,一遍写代码,

######################################
进程的三状态转换图:非常重要
1,进程一开始运行的时候,是就绪的状态,这是第一个状态,就是告诉cpu,我已经准备好可以运行了,进入排队了,
2,时间片轮转,轮到你了之后,你就运行了,这是第二个状态,
3,发生阻塞,这是第三个状态,比如你的程序让你输入内容,input方法, 这时候是阻塞的,你输入完毕了之后,就又畅通了,
这是等待I/O完成,input,sleep,文件的输入和输出,
事件处理之后,你还要进入就绪状态了,
全部处理完了,就结束了,

###########################################
同步和异步
1,同步,需要等待,需要排队,你什么也不能干,
2,异步,不需要等待,你可以去做其他事情,

###########################################
阻塞和非阻塞
1,阻塞,就是input,sleep这些,需要等待,这是阻塞,
2,非阻塞,就是跳过这些阻塞,但是程序中不可避免的需要阻塞,因为需要等待内容处理,

###########################################
同步异步和阻塞非阻塞:
同步阻塞,就是
同步非阻塞
异步阻塞
异步非阻塞,效率更高,

"""

##############################################

"""
Python中使用多进程

运行中的程序就是一个进程。所有的进程都是通过它的父进程来创建的。
因此,运行起来的python程序也是一个进程,那么我们也可以在程序中再创建进程。
多个进程可以实现并发效果,就会让程序的执行速度变快。

多进程有一个内置的模块,我们需要借助这个模块:
from multiprocessing import Process

"""

##############################################

"""
multiprocessing模块
在这个包中几乎包含了和进程有关的所有子模块。由于提供的子模块非常多,为了方便大家归类记忆,
我将这部分大致分为四个部分:
1,创建进程部分,
2,进程同步部分,
3,进程池部分,
4,进程之间数据共享。

multiprocessing.Process介绍

参数介绍
#############
Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)
强调:
1. 需要使用关键字的方式来指定参数
2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号
参数介绍:
1 group参数未使用,值始终为None
2 target表示调用对象,即子进程要执行的任务
3 args表示调用对象的位置参数元组,args=(1,2,'egon',)
4 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
5 name为子进程的名称

方法介绍
############
1 p.start():启动进程,并调用该子进程中的p.run()
2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法
3 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,
使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
4 p.is_alive():如果p仍然运行,返回True
5 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。
timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程

属性介绍
###############
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,
p不能创建自己的新进程,必须在p.start()之前设置
2 p.name:进程的名称
3 p.pid:进程的pid
4 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
5 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。
这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
"""

####################     进程的启动方式1             ############################

创建单个进程,查看主进程id,父进程id,子进程id,

注意参数的传递,args是传递一个元组,一个元素的时候要有逗号,kargs是传递一个字典,

from multiprocessing import Process
import time
import os


def task(name):
    print('{} is running!'.format(name))
    print('子进程id :', os.getpid(), '父进程id :', os.getppid()) time.sleep(3) print('{} is done!'.format(name)) # Windows开子进程要写在__name__==__main__下 # 因为开子进程会重新加载父进程的内容 if __name__ == '__main__': print('主进程id :', os.getpid()) # 创建一个Python中的进程对象 p = Process(target=task, args=('t1', )) # 注册,这是主进程 # p = Process(target=task, kwargs={'name': 't1'}) p.start() # 调用操作系统接口启动一个进程执行命令,这是子进程, # 现在子进程和主进程之间是异步的,如果我想在子进程结束之后再执行下面的代码,变成同步,怎么办? p.join() # # 这个join就是在感知一个子进程的一个结束,将异步改成同步, # print("父进程的父进程号",os.getppid()) # 这个就是pycharm的进程号, print('--- 主进程 ----') # 加上了join,这一句会在所有的子进程结束之后才会执行 """ 没有加join: 主进程id : 8560 --- 主进程 ---- t1 is running! 子进程id : 9528 父进程id : 8560 t1 is done! 加了join: 主进程id : 8592 t1 is running! 子进程id : 6448 父进程id : 8592 t1 is done! --- 主进程 ---- # 进程的生命周期, # 主进程没有开启子进程,就是执行完他的代码就结束了了 # 子进程也是执行完自己的代码就结束了, # 开启了子进程的主进程,主进程执行完了,要等待子进程结束之后,主进程才可以结束, """

创建多个进程:

from multiprocessing import Process
import time


def task(name):
    print('{} is running!'.format(name))
    time.sleep(3)
    print('{} is done!'.format(name)) if __name__ == '__main__': # 开启10个子进程 p_list = [] for i in range(10): p = Process(target=task, args=(i, )) p_list.append(p) p.start() # p.join() [p.join() for p in p_list] # 保证前面的10个进程全部结束了,才会执行下面的代码, print('--- 主进程 ----') # 这种开启了多进程,可以读多个进程去存文件,取文件内容,

#######################   进程的启动方式2       #########################

# 进程的启动方式2
# 第一点,创建一个类,继承process
# 第二点,类中必须实现run方法,这个run方法里面就是子进程要执行的内容,
import os
from multiprocessing import Process

class MyProcess(Process):  # 继承导入的process,
    def __init__(self,name):  # 为了进程能传递参数,
        super().__init__()  # 这是继承了父类所有的参数,
        self.name=name
    def run(self):
        # print(os.getpid())
        print("子进程号",self.pid)
        print("参数",self.name)  # print(os.getpid()) 这两句是一样的,


if __name__ == '__main__': # p1=MyProcess() # 这是不传参数的 p1=MyProcess("name1") # 这是传参数的,这就是面向对象的实例化, p2=MyProcess('name2') p3=MyProcess('name3') p1.start() #start会自动调用run  p2.start() # p2.run()  p3.start() # 三个进程之间是异步的,  p1.join() p2.join() p3.join() # 三个进程都结束了才会执行下面的内容,这是把异步,变成异步, print('主线程')

###############   进程之间是数据隔离的    ##############

# 进程之间的数据隔离问题
# 进程和进程之间的数据是否是隔离的,比如qq和微信,之间的数据是隔离的,
# 几个进程之间,如果不通过特殊的手段,是不可能共享一个数据的,这个记住,没有什么可理解的,

# 下面是想了一个办法,去证明这个结论,但是这个结论你记住就行了,
from multiprocessing import Process

def work():
    global n  # 声明了一个全局变量,
    n=0
    print('子进程内: ',n)


if __name__ == '__main__':
    n = 100
    p=Process(target=work)
    p.start()
    print('主进程内: ',n)

###############################################

################################################

猜你喜欢

转载自www.cnblogs.com/andy0816/p/12375624.html
今日推荐