Python中进程创建的两种方式

博客核心内容:


1、multiprocessing模块的介绍
2、Python中进程创建的两种方式
3、创建进程的相关注意事项
4、进程的常用方法总结
5、多进程在客户端和服务端的使用(多个客户端的并发效果)
6、进程与进程的关系


1、multiprocessing模块的介绍
python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing。
multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似。
multiprocessing模块的功能众多:支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。
需要再次强调的一点是:与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。

2、创建进程的两种方式
第一:继承Process类,并重写run方法
第二:直接通过进程类Process进行创建,直接指定target

进程Process类的源代码:

class Process(object):
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        self.name = ''
        self.daemon = False
        self.authkey = None
        self.exitcode = None
        self.ident = 0
        self.pid = 0
        self.sentinel = None

    def run(self):
        pass

    def start(self):
        pass

    def terminate(self):
        pass

    def join(self, timeout=None):
        pass

    def is_alive(self):
        return False

创建进程的代码示例1:

#!/usr/bin/python
# -*- coding:utf-8 -*-

from multiprocessing import Process
import time
import random

#继承Process类,并实现自己的run方法

class Piao(Process):
    def __init__(self,name):
        #必须调用父类的init方法
        super().__init__()
        self.name = name
    def run(self):
        print("%s is piaoing"%self.name)
        time.sleep(random.randint(1,3))
        print("%s is piaoeng"%self.name)


if __name__ == '__main__':
    p1 = Piao("Alex")
    #开辟一个新的进程实际上就是执行本进程所对应的run()方法
    p1.start()
    print("主进程!")

运行结果:

主进程!
Alex is piaoing
Alex is piaoeng

Process finished with exit code 0

创建进程的代码示例2:

#!/usr/bin/python
# -*- coding:utf-8 -*-

from multiprocessing import Process
import time
import random
import os


def piao(name):
    print("%s is piaoping"%name)
    time.sleep(random.randint(0,1))
    print("%s is piao end"%name)


if __name__ == '__main__':
    print("CPU的个数是:%d"%os.cpu_count())
    p1 = Process(target=piao,args=("alex",),name="进程1")
    print(p1.name)
    p1.start()
    print("父进程!") #执行速度要远快于建立新进程的时间

运行结果:

CPU的个数是:4
进程1
父进程!
alex is piaoping
alex is piao end

Process finished with exit code 0

3、创建进程的相关注意事项:http://www.cnblogs.com/linhaifeng/articles/6817679.html#_labelTop
(四)、进程 的常用方法总结
http://www.cnblogs.com/linhaifeng/articles/6817679.html
1、p1.join():主进程等待p1进程执行完毕之后才执行,注意:是主进程处于等待的状态,而子进程p1是处于运行的状态。
2、执行完p1.start()之后并不表示p1对象所对应的进程立即得到执行,p1.start()执行完之后只是表明p1对象所对应的进程具有了可以被cpu执行的资格,但是具体哪个进程先执行,哪个进程后执行则是由操作系统进行控制的,Pycharm解释器不能够直接越过操作系统对硬件cpu进行控制,因此在实际开发过程中不能够依赖进程优先级来决定线程运行的次序。
3、创建进程的开销比较大,进程创建的快慢也需要看机器的性能;同理,干死一个进程
也需要一段时间,这些都是由操作系统控制的。
4、守护进程的概念:进程分为前台进程和后台进程,后台进程唤醒的时候才运行,其中守护进程
属于后台进程。
https://zhidao.baidu.com/question/73869591.html
如何做到主进程运行完毕之后将我们开启的子进程都给回收掉:利用守护进程,将相应的子进程设置为守护进程,这样主进程运行完毕之后,相应的守护进程就会被回收掉。
设置的方法:在p1.start之前将p1.daemon = True
示例程序1:Python中进程的常用方法总结

#!/usr/bin/python
# -*- coding:utf-8 -*-

from multiprocessing import Process
import random
import os
import time

"""
1、    p1.join():只有子进程p1运行完毕之后,父进程才会向下执行
2、

"""
def piao(name):
    print("%s is piaoing"%name)
    time.sleep(random.randint(1,3))
    print("%s is piaoend"%name)

if __name__ == '__main__':
    p1 = Process(target=piao,args=("alex",))
    p2 = Process(target=piao, args=("wupeiqi",))
    p3 = Process(target=piao, args=("yuanhao",))
    p4 = Process(target=piao, args=("egon",))

    p_l = [p1,p2,p3,p4]
    for p in p_l:
        p.start()

    for p in p_l:
        p.join()

    print("主进程执行完毕!")

运行结果:

alex is piaoing
wupeiqi is piaoing
egon is piaoing
yuanhao is piaoing
wupeiqi is piaoend
alex is piaoend
egon is piaoend
yuanhao is piaoend
主进程执行完毕!

Process finished with exit code 0

示例程序2:Python中常用方法总结

#!/usr/bin/python
# -*- coding:utf-8 -*-

from multiprocessing import Process
import random
import os
import time

"""
1、    p1.join():只有子进程p1运行完毕之后,父进程才会向下执行
2、

"""
def piao(name):
    print("%s is piaoing"%name)
    time.sleep(random.randint(1,3))
    print("%s is piaoend"%name)

if __name__ == '__main__':
    p1 = Process(target=piao,args=("alex",))
    p2 = Process(target=piao, args=("wupeiqi",))
    p3 = Process(target=piao, args=("yuanhao",))
    p4 = Process(target=piao, args=("egon",))

    p1.start()  #开辟一个新的进程,并执行本进程所对应的run方法
    p1.join()

    p2.start()
    p2.join()

    p3.start()
    p3.join()

    p4.start()
    p4.join()


    print("主进程")

运行结果:

alex is piaoing
alex is piaoend
wupeiqi is piaoing
wupeiqi is piaoend
yuanhao is piaoing
yuanhao is piaoend
egon is piaoing
egon is piaoend
主进程

Process finished with exit code 0

守护进程的运行示例:

#!/usr/bin/python
# -*- coding:utf-8 -*-

from multiprocessing import Process
import random
import os
import time

"""
1、    p1.join():只有子进程p1运行完毕之后,父进程才会向下执行
2、

"""
def piao(name):
    print("%s is piaoing"%name)
    time.sleep(random.randint(1,3))
    print("%s is piaoend"%name)

if __name__ == '__main__':
    p1 = Process(target=piao,args=("alex",),name="p1")
    #将p1这个进程设置为后台的守护进程
    p1.daemon = True
    #开启这个后台的守护进程
    p1.start()

    print(p1.name)
    print(p1.pid)

    print("主进程")
    #事实证明,后台的这个守护进程直接被干死了
    print("主进程执行完毕之后,守护进程立即被回收掉,即立即死掉!")

运行结果:

p1
10512
主进程
主进程执行完毕之后,守护进程立即被回收掉,即立即死掉!

五、多进程在客户端和服务端的使用(多个客户端的并发效果)
相关知识:
进程的一个应用实例:客户端和服务端
之前的问题:客户端不能并发,如何通过多进程达到并发的效果?
并发的是链接的循环,而不是通信的循环!
每次来一个链接我就启动一个任务进行相应的处理.
而启动任务就是启动进程。
在实际的工作当中,有几个cpu就应该开启几个进程,而不应该在我们的机器上面无限的
开启多个进程,无限的启动多个进程实际上没有什么用,因为启动多个进程实际上是为了使用
多核的优势,让任务的并行的进程处理。

进程太多的话,实际上回拖慢程序的运行速度,因为进程会占用独立的内存空间。

进程的数量可以进程设置,最少多个进程,最多多少个进程,始终将进程的数量维持在一个范围之内,
这样既保证了并发的效果,又保证了合理的并发数,这就是进程池。
代码示例:http://blog.csdn.net/a2011480169/article/details/73602708
(六)进程与进程的关系

进程与进程的关系:
进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或者同一个打印终端,是没有
问题的。
即多进程共享一个打印终端,多进程共享同一套文件系统。
模拟10万个进程同时向终端打印数据:
代码示例:

#!/usr/bin/python
# -*- coding:utf-8 -*-


from multiprocessing import Process
import time
import random


def piao(name):
    print(name)


if __name__ == '__main__':
    for i in range(10000):
        p = Process(target=piao,args=("进程%s"%i,))
        p.start()

标签