爱陪小樱桃

导航

 

标签(空格分隔): 开启进程的方式


multiprocessing模块介绍:

python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。

Python提供了multiprocessing。 multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,>提供了Process、Queue、Pipe、Lock等组件。

需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。

Process类的介绍

创建进程的类:

Process([group [, target [, name [, args [, kwargs]]]]]),由该类实例化得到的对象,可用来开启一个子进程

强调:

  1. 需要使用关键字的方式来指定参数
  2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号

参数介绍:
group参数未使用,值始终为None
target表示调用对象,即子进程要执行的任务
args表示调用对象的位置参数元组,args=(1,2,'egon',)
kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
name为子进程的名称
属性介绍:

p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
p.name:进程的名称
p.pid:进程的pid

例如:如下代码开启进程的方式一:

from multiprocessing import Process
import time
def task(name):
    print('%s is running ' %name)
    time.sleep(3)
    print('%s is done ' %name)
if __name__ == '__main__':
    p=Process(targe=task,args=('子进程1'))
    p.start()#仅仅是给子系统发送了一个信号
    print('主')

执行结果:

主
子程序 is running 
子程序 is done 

大家可以看到执行程序的结果为:先打印“主”,然后创建子程序;

# 方式二:
class MyProcess(Process):
    def __init__(self,name):
        super(MyProcess, self).__init__()
        self.name=name
    def run(self):
        print('%s is running ' %self.name)
        time.sleep(3)
        print('%s is done ' %self.name)
if __name__ == '__main__':
    p=MyProcess('子进程1')
    p.start()
    print('主')
执行结果:
主
子进程1 is running 
子进程1 is done 

如上图是开启子进程的两种方式,结果一样,只是实现的方式不一样;

方法介绍:

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

查看进程的pid与ppid

大家知道我们在管理人的时候,通过大家的身份证来识别,那么操作系统呢,操作系统在识别各种进程的时候,怎么区分呢?

同理:
操作系统管理进程也是一样:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from multiprocessing import Process
import time,os
def task():
    print('%s is running' %os.getpid())
    time.sleep(3)
    print('%s is done' %os.getpid())
if __name__ == '__main__':
    p=Process(target=task,)
    p.start()
    print('主 %s' %os.getpid())

执行结果:

主 3254
3255 is running
3255 is done

查看父进程:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from multiprocessing import Process
import time,os
def task():
    print('%s is running' %os.getpid(),os.getppid())
    time.sleep(3)
    print('%s is done' %os.getpid(),os.getppid())
if __name__ == '__main__':
    p=Process(target=task,)
    p.start()
    print('主 %s' %os.getpid(),os.getppid())

执行结果为:

('\xe4\xb8\xbb 3482', 2583)
('3483 is running', 3482)
('3483 is done', 3482)

上述结果可以查看,2583是这个主进程的父进程,那就应该是pycharm运行这个程序的进程,大家可以自己查看一下pycharm的进程id就可以知道了;

![image.png-180.1kB][1]
如图可以看到上述的2583是pycharm进程;

僵尸进程和孤儿进程:

('\xe4\xb8\xbb 3482', 2583)
('3483 is running', 3482)
('3483 is done', 3482)

上述的第一行,是父进程结束了,大家可以看到父进结束了,父进程在等着子进程运行,那么为什么父进程运行完了还要等着子进程呢?

父亲生了10个儿子,儿子干什么工作就和自己没关系了,但是父亲可以去看看儿子;
所以说要实现一种逻辑就是:父进程什么时候去看他的儿子都可以看到,即使儿子已经死掉了,也要保留一个躯体,--这就是僵尸进程,
僵尸进程,是Linux为我们提供的一种状态,虽然内存空间清理了,但是状态在,就是为了父亲看的时候方便,父亲可为他收尸;父亲可以回收;

所有的子进程都要经力僵尸进程;
僵尸进程有害吗?
有害:进程还有pid,僵尸多了,pid会被占用,一堆僵尸进程,导致机器开不了进程;

孤儿进程:

没有父进程,就是孤儿进程,儿子没死,爹死了就是孤儿进程;
孤儿进程,无害,
[1]: http://static.zybuluo.com/wangcherry123/0ilnmwl0e56zasuy179osz92/image.png

posted on 2018-10-30 23:06  cherry小樱桃  阅读(235)  评论(0编辑  收藏  举报