进程池 pool

1.获取cpu的核心数(逻辑处理器的数量)

cpu_count()

import os
res = os.cpu_count()
print(res) # 4

2.进程池

注意:

Process 和 Pool 区别:
  Process : 属于异步并发程序,主进程会默认等待子进程全部执行完毕之后,在终止程序
  Pool : 属于异步并行程序,在没有任何阻塞的情况下,只要主进程执行完毕,会立刻终止所有子进程;
p = Pool(6):
  代表同一时间最多允许并行6个进程;

进程池pool里面的参数
  如果Pool不加任何参数,默认使用的是os.cpu_count()获取到的数量,逻辑处理器
  如果加了参数,就使用当前参数值,所代表的是同一时间最大允许的进程数(并行)

在进程池中,如果一个进程执行任务的速度太快,会包揽更多的任务执行,就不会创建新的进程

from multiprocessing import Process,Pool
import os,time,random

# (1)比较进程池和进程之间的速度 => 进程池速度更快
def func(num):
    print(os.getpid())
    print(num)
    time.sleep(0.1)
    for i in range(1000000):
        pass
if __name__ == '__main__':
    # 记录开始时间
    startime = time.time()
    # 1.创建进程池
    p = Pool(4)
    for i in range(100):
        p.apply_async(func,args=(i,))
    # 3.关闭进程池
    p.close()
    # 4.udp循环发消息.等待子进程全部执行结束之后,再向下执行
    p.join()
    # 记录结束时间
    endtime = time.time()
    print("1号运行的时间是:",endtime-startime) # 3.7787575721740723
    print("进程池运行结束。。。")

    # 计算prosess运行的时间
    stratime = time.time()
    lst = []
    for i in range(100):
        p = Process(target=func,args=(i,))
        p.start()
        lst.append(p)

    for i in lst:
        i.join()
    endtime = time.time()
    print("2号运行的事件是:",endtime-startime) # 4.udp循环发消息.919969081878662
    print("process运行结束。。。")

2.2 apply 同步程序,可以直接获取子进程中的返回值 (了解)

from multiprocessing import Process,Pool
import os,time,random
def task(num):
    print("num:%s 进程号%s"%(num,os.getpid()))
    return os.getpid()

if __name__ == '__main__':
    # 同一时间最多运行并行4个进程
    p =Pool(4)
    for i in range(20):
        res = p.apply(task,args=(i,))
        print(">>>>",res)
    print("主程序执行结束")

2.3apply_async 异步程序,可以直接通过get获取子进程中的返回值

from multiprocessing import Process,Pool
import os,time,random
def task(num):
    print("num:%s 进程号%s"%(num,os.getpid()))
    return os.getpid()

if __name__ == '__main__':
    # 同一时间最多运行并行4个进程
    p =Pool(4)
    for i in range(20):
        res = p.apply(task,args=(i,))
        print(">>>>",res)
    print("主程序执行结束")

# (3)apply_async 异步程序,可以直接通过get获取子进程中的返回值

def task(num):
    time.sleep(random.uniform(0.1,1))
    print("num:%s 进程号%s"%(num,os.getpid()))
    return os.getpid()

if __name__ == '__main__':
    lst = []
    setvar = set()
    p = Pool()
    for i in range(20):
        res = p.apply_async(task,args=(i,)) # <multiprocessing.pool.ApplyResult object at 0x7f821508fa58>
        lst.append(res)

    print(lst)
    for i in lst:
        # 用来获取当前子进程的返回值,get函数本身含有阻塞,不加close和join一样可以
        res = i.get() # 获取对象中的值,就是进程号
        print(res)
        setvar.add(res)

    print(setvar) # {37066, 37067, 37068, 37069}

    # 3.关闭进程池
    p.close()
    # 4.udp循环发消息.等待子进程全部执行结束之后,再向下执行
    p.join()

    print("finish....")

2.4 map (与高阶函数map使用方法一样,区别在于并发和并行) 返回列表

from multiprocessing import Process,Pool
import os,time,random
def task(num):
    print("num:%s 进程号%s"%(num, os.getpid()))
    time.sleep(0.1)
    return num **2

if __name__ == '__main__':
    p = Pool()
    res = p.map(task,range(100))
    print(res)
    print("主进程 finish")

2.5 close 和 join 同时使用,或者同时不适用,必须是一对

from multiprocessing import Process,Pool
import os,time,random
def task(num):
    print("num:%s 进程号%s"%(num,os.getpid()))
    time.sleep(0.1)
    return num **2

if __name__ == '__main__':
    lst = []
    p = Pool()
    for i in range(20):
        # res返回的是异步的进程对象
        res = p.apply_async(task,args=(i,))
        lst.append(res)


    for i in lst:
        # 在获取返回值的同时,加了阻塞
        print(i.get())


    # 关闭进程池
    # p.close()
    # # p.apply_async(task,args=(100,))
    # p.join()

    print("主进程 finish")

猜你喜欢

转载自www.cnblogs.com/youhongliang/p/11871776.html