python之路---并发编程之进程&开启进程的两种方式

什么是进程

进程是指一个程序在一个数据集上的动态执行过程(程序执行过程的抽象)

进程包含

程序:我们通过程序来描述一个进程所要执行的内容以及如何执行

数据集:数据集代表程序在执行过程中所需要的资源

进程控制块:用于描述进程的外部特征,记录进程的执行过程,系统可以用来控制,管理进程,也是操作系统感知进程存在的唯一标识

进程执行的三种状态:阻塞/运行/就绪

python之路---并发编程之进程&开启进程的两种方式_第1张图片

1.进程执行过程中出现IO,进入阻塞状态(操作系统强行剥夺CPU)

2.进程占用CPU时间过长/出现一个优先级更高的进程,进入就绪状态(CPU被剥夺)

3.就绪态的进程被分配到CPU,进入运行状态

4.阻塞态的进程出现有效输入,进入就绪态,等待操作系统分配CPU

此外,我们能直接控制的只有阻塞状态,减少阻塞,使进程尽可能的保持在就绪状态,提高效率

 进程的创建

4个创建新进程的主要方式:1 系统初始化 2 在一个进程内开启另一个子进程 3 用户交互(双击微信) 4 一个批处理作业的初始化

上述开启新进程的方式其实都是由一个已经存在的进程执行一个用于创建新进程的系统调用

其中,UNIX使用fork,window使用createProcess创建进程

两者的异同点

相同:父进程与子进程都属于不同的内存空间,在其内存空间内修改变量不会影响到其它进程(多道技术的空间复用就要求进程之间的内存空间是隔离的,且这种隔离是物理层面的)

不同:UNIX中子进程的初始地址空间是父进程的一个副本(可以有只读的内存共享空间),而window中,子进程与父进程的内存空间地址从一开始就是不同的

此外,在window中没有进程层次的概念,对于操作系统来说所有进程的地位都相同(对于父进程,在创建子进程的时候会获得一个句柄,用于控制子进程,而这个句柄可以传给其它子进程)

 开启进程的两种方式

方式一:调用内置的类

from multiprocessing import Process


def func(name):
    print('%s,running...' % name)
    print('%s,ending...' % name)


if __name__ == '__main__':
    obj = Process(target=func, args=('子进程一',))  
# 如果只有一个参数,args括号内一定要加逗号,确保以元组的形式传入
    obj.start() 
 # 只是主进程给操作系统发送建立子进程的请求,并非立刻建立子进程
    print('主>>>')

方式二:自定义类

class MyProcess(Process):
    def run(self):  # 必须为这个名字
        print('%s running...' % self.name)
        print('%s ending...' % self.name)


if __name__ == '__main__':
    obj = MyProcess()
    obj.start()  # 本质上是在调用父类的start方法,而start方法下会触发run方法
    print('主>>>')

为什么开启进程要在main内执行

Since Windows has no fork, the multiprocessing module starts a new Python process and imports the calling module. 
If Process() gets called upon import, then this sets off an infinite succession of new processes (or until your machine runs out of resources). 
This is the reason for hiding calls to Process() inside

简言之,是由于在windows系统下,子进程是通过导入模块的方式拿到父进程的代码,如果没有main会一直开启子进程,而子进程的申请是需要开辟内存以及申请pid等的

 

你可能感兴趣的