<style></style>
Python学习day35-并发编程(1)
进程的基础
顾名思义,进程就是程序正在执行的一个过程.进程的概念最早是来源于操作系统,是操作系统最核心的概念,所以要真正了解进程,必须事先了解操作系统.
https://www.cnblogs.com/Xu-PR/p/11246347.html
简单来说,因为早期的计算机只有一个cpu,也能支持并发(伪并行)的能力.或者是将一个单独的cpu变成多个虚拟的cpu(也就是多道技术:时间多路复用和空间多多路复用+硬件上支持隔离).
什么是进程
官方的话来说,进程(Process)就是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,也是操作系统结构的基础.
狭义来说,进程是正在运行的程序的实例
广义来说,进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动.是操作系统动态执行的基本单元,在传统的操作系统中,进程即是基本的分配单元,又是基本的执行单元.
同一个程序执行两次,就会在操作系统中出现两个进程,这两个进程是互不干扰的,相互独立的,所以我们可以同时运行一个软件,分别做不同的事情,也不会混乱.
进程的并行和并发
-
并发:并发是指资源有限的情况下,两者或者更多的使用者轮流使用资源,并发是一种伪并行,实际上并发同一时间还是只能被一个使用者使用,只是可以交替使用,从而提高效率
-
并行:并行是指两者同时执行,是真正的同时执行,不是并发那样看似像是同时进行,并行的最基础的条件就是多核,或者说是多个大脑,资源够用的情况下,才可以并行.
其区别:
并行是从微观上,也就是在一个精确的时间片刻,有不同的程序在执行,就必须有多个处理器,来实现并行.
并发是从宏观上看的,在一个时间段内可以看做是同时执行,比如一个服务器要同时处理多个session,实际上是并发,而不是并行.
进程的创建和结束
进程的创建
实际上,新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的.
- Windows创建进程是调用的CreateProcess,这个指令负责处理进程的创建,同时也负责把正确的程序装入新进程里
- 在UNIX系统中,系统调用是fork,fork会创建一个与父进程一模一样的副本,二者有相同的存储印象,同样的环境字符串和同样的打开文件,实际上在shell解释器进程中,执行一个命令就会创建一个子进程.子进程和父进程是可以有只读的共享内存区的,但是对于Windows来说,从一开始父进程和子进程的地址空间就是不同的.
进程的结束
- 正常退出(自愿的,linux中用exit,Windows中用ExitProcess,或者各种界面化的关闭,关机等)
- 出错退出(自愿的,比如python中文件不存在)
- 严重错误(非自愿,执行非法指令,如引用不存在的内存,1/0等,可以通过捕捉异常来避免这种错误)
- 被其他进程杀死(非自愿,比如kill -9)
模块multiprocess
其实究其根本来说,multiprocess不是一个模块,而是python中一个操作,管理进程的包.其中的multi就是取自mulitiple的多功能的意思.
Process模块时一个创建进程的模块,借助这个模块我们就可以完成进程的创建.
Process模块的简单使用
点开Process的源码,我们可以看到以下内容
xxxxxxxxxx1 25 1
class Process(object):2
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):3
self.name = ''4
self.daemon = False5
self.authkey = None6
self.exitcode = None7
self.ident = 08
self.pid = 09
self.sentinel = None10
11
def run(self):12
pass13
14
def start(self):15
pass16
17
def terminate(self):18
pass19
20
def join(self, timeout=None):21
pass22
23
def is_alive(self):24
return False25
'''26
其中的参数含义为:27
1. group,默认为None,不用赋值28
2. target为调用对象,可以是函数,或者类29
3. args表示调用对象的位置参数元组,注意,必须是元组30
4. kwargs为调用对象的字典,注意,必须是字典31
5. name为子进程的名称,这个可以任意定义32
33
属性的含义为:34
1. p.daemon(),默认值为False,如果设置成True就代表p是后台运行的守护进程,p的父进程终止的时候p也要随之终止,且p不能创建自己的新进程35
2. p.name(),就是子进程的名字36
3. p.pid(),子进程的pid37
4. p.exitcode(),没有大用,不必理会38
5. p.authkey(),暂时不用了解39
40
其中的一些方法的含义为:41
1. p.run(),进程启动时会自动运行的方法,不必手动去调用,所以我们可以在这个方法里写入想要实现或者赋值的一些语句42
2. p.start(),启动进程,并自动调用子进程中的run(),需要手动调用43
3. p.terminate(),强制终止进程,但不会进行清理操作,容易产生僵尸进程,要谨慎使用44
4. p.join(),主线程等待p终止,注意,是主线程在等,p子进程还是在运行的状态,括号里是可以写等待超时的时间,但是join只能等待用start开启的进程,用run开启的不能用45
5. p.is_alive(),判断子进程p是否还在运行,如果在运行返回True,如果没有运行返回False46
'''
很显然这是一个类,所以我们可以通过对这个类实例化来产生对象.
需要注意的几点是:
- 我们必须用关键字的方式来指定参数,比如
Process(target = func,name = nick,args = (,))
- args是指定的为target所指的函数的位置参数,是一个元组的形式,至少要有一个逗号,就算只有一个值也要有一个逗号.