python中进程之multiprocessing模块

1、启动进程实现多任务
现代操作系统(windows,Mac OS X ,Linux等)
多任务:操作系统可以运行多个任务
早期的cpu都是单核cpu实现多任务原理:操作系统轮流让各个任务交替执行,任务反复执行下去,但是cpu调度执行太快,导致感觉多有任务都在同时执行
多核cpu执行多任务原理:真正的并行执行多任务只能在多核cpu上实现,但是由于 任务数量远远超过cpu的核心数量,所以操作系统也会自动将很多任务轮流的调度到每个核心上执行
并发:看上去一起执行,任务数多余cpu核心数
并行:真正一起执行,任务书小于等于cpu核心数(效率最高)
实现多任务方式:
1、多进程模式
2、多线程模式
3、协程模式
4、多进程加上多线程模式

进程:
对于操作系统而言一个任务就是一个进程
进程是系统中程序执行和分配的基本单位,每个进程都有自己的数据段,代码段和堆栈段

单任务现象

from time import sleep

def run():
    while True:
        print("123")
        sleep(1.2)
if __name__ == "__main__":
    while True:
        print("456")
        sleep(1)
    #不会执行这个方法只有等上面的while执行完才能执行
    run()

启动进程实现多任务

from multiprocessing import Process
from time import sleep
import os
#子进程需要执行的代码
#os.getid获取当前进程的id号
#os.getppid获取当前进程的父进程的id号
def run(str):
    while True:
        print("sunck is a %s man--%s--%s "% (str, os.getpid(),os.getppid()))
        sleep(1.2)

if __name__ == "__main__":
    print("主进程启动--%s"%(os.getpid()))
    # 创建一个子进程在主进程之前启动
    # target说明进程的执行任务
    p = Process(target=run,args=("nice",))
    # 启动子进程
    p.start()
    while True:
        print("456")
        sleep(1)

2、启动多个子进程

from multiprocessing import Pool
import os,time,random


def run(name):
    print("子进程%d开始--%s" % (name,os.getpid()))
    start = time.time()
    time.sleep(random.choice([1,2,3]))
    end = time.time()
    print("子进程%d结束--%s--耗时%.2f" % (name,os.getpid(),end-start))


if __name__ == "__main__":
    print("父进程启动--%s" % (os.getpid()))
    #创建多个进程
    #Pool进程池
    #4表示可以同时执行的进程数量,如果不写默认的是cpu核心数
    pp = Pool(2)
    #range中的数必须大于Pool中的数才能看出效果
    for i in range(4):
        #创建进程放入进程池统一管理
        pp.apply_async(run,args=(i,))
    #在调用join之前必须先调用close,并且调用close之后不能再继续添加新的进程了
    pp.close()
    #进程池对象调用join,会等待进程池中所有的子进程结束完毕再去执行父进程
    pp.join()
    print("父进程结束--%s" % (os.getpid()))
父进程启动--8008
子进程0开始--11692
子进程1开始--2996
子进程0结束--11692--耗时2.00
子进程2开始--11692
子进程1结束--2996--耗时3.00
子进程3开始--2996
子进程2结束--11692--耗时2.00
子进程3结束--2996--耗时2.00
父进程结束--8008

3、全局变量不能在多个子进程中共享

from multiprocessing import Process

num = 100

def run():
    print("子进程开始")
    global num
    num += 1
    print("%d" % num)
    print("子进程结束")


if __name__ == "__main__":
    print("父进程开始")
    p = Process(target=run)
    p.start()
    p.join()

    p2 = Process(target=run)
    p2.start()
    p2.join()
    print("父进程结束--%d" % (num))
父进程开始
子进程开始
101
子进程结束
子进程开始
101
子进程结束
父进程结束--100

4、封装继承对象

from multiprocessing import Process
import os,time

class SunckProcess(Process):
    def __init__(self,name):
        Process.__init__(self)
        self.name = name

     def run(self):
         print("子进程(%s-%s)启动"%(self.name,os.getpid()))
         #子进程的功能
         time.sleep(3)
         print("子进程(%s-%s)结束" % (self.name, os.getpid()))

if __name__ == "__main__":
    print("子进程启动")
    #创建子进程
    p = SunckProcess("test")
    #自动调用进程对象
    p.start()
    p.join()
    print("父进程结束")

5、父子进程的先后顺序

from multiprocessing import Process
from time import sleep


def run(str):
    print("启动子进程")
    sleep(3)
    print("子进程结束")

if __name__ == "__main__":
    print("父进程启动")
    p = Process(target=run,args=("nice",))
    p.start()
    #父进程的结束不能影响子进程,让父进程等待子进程结束再执行父进程
    p.join()
    print("父进程结束")

6、用进程拷贝文件

import os,time


#拷贝文件def copyFile(rPath,wPath):
    fr = open(rPath,"rb")
    fw = open(wPath,"wb")
    context = fr.read()
    fw.write(context)
    fr.close()
    fw.close()

path = r"D:\py2"
toPath = r"D:\py3"


#读取path下所有的文件
start = time.time()
fileList = os.listdir(path)
for fileName in fileList:
    copyFile(os.path.join(path,fileName),os.path.join(toPath,fileName))
end = time.time()
print("总耗时%.2f" % (end-start))

多进程拷贝文件比单进程快

from multiprocessing import Pool
import os,time


def copyFile(rPath,wPath):
    fr = open(rPath,"rb")
    fw = open(wPath,"wb")
    context = fr.read()
    fw.write(context)
    fr.close()
    fw.close()

path = r"D:\py2"
toPath = r"D:\py3"

7、进程间的通信

from multiprocessing import Process,Queue
import os,time


def write(q):
    print("启动写子进程%s" % (os.getpid()))
    for chr in ["A","B","C","D"]:
        q.put(chr)
        time.sleep(1)
    print("结束写子进程%s" % (os.getpid()))

def read(q):
    print("启动读子进程%s" % (os.getpid()))
    while True:
        value = q.get(True)
        print("value = " + value)
    print("结束读子进程%s" % (os.getpid()))


if __name__ == "__main__":
    print("父进程启动")
    #父进程创建队列,并传递给子进程
    q = Queue()
    pw = Process(target=write,args=(q,))
    pr = Process(target=read,args=(q,))
    pw.start()
    pr.start()

    pw.join()
    #pr进程里面是个死循环,无法等待其结束,只能强行结束
    pr.terminate()
    print("父进程结束")

猜你喜欢

转载自blog.csdn.net/qq_41114516/article/details/83046534