python--多进程、进程池、进程通信

1、多进程

from time import sleep    # 休眠
from multiprocessing import Process
import os

"""
os.getpid() : 获得当前进程号
os.getppid(): 获得父进程号
p = Process(任务,任务名):创建一个进程
p.start() :   开始进程
p.terminate():终止进程
"""
def task(s,name):
    while True:
        sleep(s)
        print("这是task",os.getpid(),"----------",os.getppid(),"time:",s,"name:",name)
        # 这是task 13476 ---------- 14736

def task1(s,name):
    while True:
        sleep(2)
        print("这是task1",os.getpid(),"----------",os.getppid(),"time:",s,"name:",name)
        # 这是task1 14136 ---------- 14736


if __name__ == '__main__':
    print("**********",os.getpid())

    # p和p1进程为子进程,因为python解释器pycharm是主进程
    p = Process(target=task,name="task",args=(1,"tv"))      # 创建1个任务 args传几个参数,task就接几个参数
    # p = Process(target=函数, name=进程名, args=传参)
    p.start()                                 # 该任务开始执行
    print(p.name)                             # 该任务的名字

    p1 = Process(target=task1,name="task1",args=(2,"cp"))
    p1.start()
    print(p1.name)

    number = 1
    while True:
        number += 1
        # sleep(0.2)
        if number == 50:
            p.terminate()
            p1.terminate()
            break
        else:
            print("-------------",number)


# 控制台打印:
"""
task
task1
-------------
***********         # 主进程进行的事情
                    # 下面是子进程进行的事情
这是task
这是task1
这是task
这是task
这是task1
这是task
这是task
...
Process finished with exit code -1
"""

2、进程池

from multiprocessing import Pool  # 创建池子
import time
import random
import os
# # 多个进程,两个进程的话自己创建就可以了
"""
阻塞式进程:一次性进入

非阻塞式进程:一个一个进入,相当于先加到队列里,有队列进入池子,可以设置进程数量,还可以进程复用。
结束就返回,其他的就可以进入。回调是谁先结束谁去回调函数去记录一下
回调函数等任务完成就调用
"""
# 非阻塞
def task(task_name):
    print("start doing",task_name)
    start = time.time()
    # sleep
    time.sleep(random.random()*2)
    end = time.time()
    # todo 如果将结束放到这里,那么,就会在每个任务完成时打印一下
    # print("finish task:{},use time:{},process id:{}".format(task_name,(end-start),os.getpid()))
    return "finish task:{},use time:{},process id:{}".format(task_name,(end-start),os.getpid())

# 用于下面的回调函数
# todo 如果使用回调函数,将其放入容器中(列表)
container = []
def callback_func(n):
    container.append(n)

if __name__ == '__main__':
    pool = Pool(5)  # param: process,num
    tasks = ["listen","write","washes","play","run","read","look","doctor"]
    for task1 in tasks:
        pool.apply_async(task,args=(task1,),callback=callback_func)  # 非阻塞式 param:func、异步
    # 使用进程池,必须让主进程一直进行,即pycharm一直进行
    pool.close()  # 添加任务结束
    pool.join()  # 让主进程一直进行
    # todo 结束时,打印容器中的内容,提醒已经完成的任务有哪些
    for i in container:
        print(i)
    # 提醒结束
    print("over")

"""
start doing listen
start doing write
start doing washes
start doing play
start doing run
start doing read
start doing look
start doing doctor
finish task:listen,use time:0.035909175872802734,process id:20524
finish task:washes,use time:0.3520622253417969,process id:21344
finish task:look,use time:0.19447803497314453,process id:21344
finish task:run,use time:0.8018584251403809,process id:9484
finish task:write,use time:1.604302167892456,process id:21348
finish task:doctor,use time:1.3295471668243408,process id:21344
finish task:read,use time:1.8770811557769775,process id:20524
finish task:play,use time:1.977813720703125,process id:8748
over
"""

3、进程通信

from multiprocessing import Process,Queue
from time import sleep


def download(q):
    images = ["1.png","2.png","3.png"]
    for image in images:
        print("正在下载:",image)
        sleep(0.5)
        q.put(image)  # 放文件


def getfile1(q):
    file = q.get()  # 取文件,不放文件就不取。,而且只取一次
    print("{}保存成功".format((file)))


def getfile2(q):
    while True:     # 一直取,但是程序不会停下来了
        file = q.get()
        print("{}保存成功".format((file)))


def getfile(q):
    while True:
        try:  # 加等待时间和超时退出
            file = q.get(timeout=2)
            print("{}保存成功".format((file)))
        except:
            print("全部保存完了")
            break


if __name__ == '__main__':
    # 进程中的队列,两个进程共用一个队列
    q = Queue(5)
    # python文档
    # 使用args传q对象
    p1 = Process(target=download,args=(q,))  # 进程名,不需要加括号,加括号的是调用进程
    p2 = Process(target=getfile,args=(q,))

    p1.start()
    p1.join()  # 阻塞一下进程。不阻塞的话就先打印over,不是自己想要的结果

    p2.start()
    p2.join()

    print("over")

"""
正在下载: 1.png
正在下载: 2.png
正在下载: 3.png
1.png保存成功
2.png保存成功
3.png保存成功
全部保存完了
over
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值