美文网首页
【第53天】python全栈从入门到放弃

【第53天】python全栈从入门到放弃

作者: 36140820cbfd | 来源:发表于2019-08-17 21:48 被阅读0次

1进程之间共享内存

代码块
#进程之间共享内存
from multiprocessing import Manager,Process

def func(a,b):
    a[0]=666
    b['name']='alex'

    print('子进程的结果是',a,b)


if __name__=='__main__':
    m=Manager()
    lst=m.list([1,2,3])
    dic=m.dict({'name':'wangsiyu'})
    p=Process(target=func,args=(lst,dic,))
    p.start()
    p.join()
    print('父进程的结果是',lst,dic)

2进程池的异步任务处理,返回1-10000之间的数字

代码块
from multiprocessing import Pool    #导入进程池
import time

def func(num):  #这个函数的作用是把传过来的每个值+1
    num += 1
    print(num)

if __name__ == '__main__':
    p = Pool(5)
    start = time.time()
    l = []
    for i in range(10000):
        res = p.apply_async(func,args=(i,))# 异步处理这10000个任务,异步是指,进程中有5个进程,一下就处理5个任务,5个5个执行,
        # 接下来哪个进程处理完任务了,就马上去接收下一个任务
        l.append(res)
    p.close()
    p.join()
    print(time.time() - start)
    [print(i.get()) for i in l]

3进程池的同步任务处理

代码块
from multiprocessing import Pool
import time


def func(num):
    num += 1
    return num

if __name__ == '__main__':
    p = Pool(5)
    start = time.time()
    for i in range(10000):
        res = p.apply(func,args=(i,))# 同步处理这10000个任务,同步是指,哪怕我进程中有5个进程,也依旧是1个进程1个进程的去执行任务
        # time.sleep(0.5)
        print(res)
    print(time.time() - start)

4 多进程做任务和进程池做任务的效率对比

代码块
import os
from multiprocessing import Pool,Process
import time

def func(num):
    num += 1
    print(num)

if __name__ == '__main__':
    p = Pool(os.cpu_count() + 1)
    start = time.time()
    p.map(func,[i for i in range(100)])
    p.close()# 指不允许在向进程池中添加任务
    p.join()# 等待进程池中所有进程执行完所有任务
    print('进程池做任务的效率:',time.time() - start)
    start = time.time()
    
    
    lst = []
    for i in range(100):
        p1 = Process(target=func,args=(i,))
        p1.start()
        lst.append(p1)
    [i.join() for i in lst]
    print('多进程直接做任务的效率',time.time() - start)
    # p.apply()是指让进程池中的进程,同步的帮你做任务
    # p.apply_async()# 是指让进程池中的进程,异步的帮你做任务

5 map(func,可迭代对象)的返回值

代码块
from multiprocessing import Pool

def func(num):
    num += 1
    print(num)
    return 'hello'    #注意,map函数的返回值返回的东西,就看return后面跟的是什么,就返回什么

if __name__ == '__main__':
    p = Pool(5)
    res = p.map(func,[1,2,3,4,5])
    p.close()
    p.join()
    print('主进程中map的返回值',res)

6 异步

代码块
from multiprocessing import Pool
import requests
import time

def func(num):
    time.sleep(0.5)
    print(num+1)

if __name__ == '__main__':
    p = Pool(5)
    for i in range(100):
        p.apply_async(func, args=(i,))
        # time.sleep(0.5)
    p.close()
    p.join()

7 同步和异步效率

代码块
from multiprocessing import Pool
import requests
import time

def func(url):
    res = requests.get(url)
    print(res.text)    #把拿到的源代码以文本形式打印下来
    if res.status_code == 200:  #状态是成功
        return 'ok'

if __name__ == '__main__':
    p = Pool(5)
    l = ['https://www.baidu.com',
         'http://www.jd.com',
         'http://www.taobao.com',
         'http://www.mi.com',
         'http://www.cnblogs.com',
         'https://www.bilibili.com',
         ]

    #同步
    start = time.time()
    for i in l:
        p.apply(func,args=(i,))

    apply_= time.time() - start

    #异步
    start = time.time()
    for i in l:
        p.apply_async(func, args=(i,))
    p.close()
    p.join()
    print('同步的时间是%s,异步的时间是%s'%(apply_, time.time() - start))

8 回调函数rollback()

代码块
from multiprocessing import Pool
import requests
import time,os

def func(url):
    res = requests.get(url)
    print('子进程的pid:%s,父进程的pid:%s'%(os.getpid(),os.getppid()))
    # print(res.text)
    if res.status_code == 200:
        return url,res.text

def cal_back(sta):
    print('回调函数的pid', os.getpid())
    url,text = sta
    with open('a.txt','a',encoding='utf-8') as f:
        f.write(url + text)

if __name__ == '__main__':
    print('主进程的pid', os.getpid())
    p = Pool(5)
    l = ['https://www.baidu.com',
         'http://www.jd.com',
         'http://www.taobao.com',
         'http://www.mi.com',
         'http://www.cnblogs.com',
         'https://www.bilibili.com',
         ]

    for i in l:
        p.apply_async(func, args=(i,),callback=cal_back)
        # 异步执行任务func,每有一个进程执行完任务后,在func中return一个结果,结果会自动的被callback指定的函数接收
    p.close()
    p.join()

9 进程池知识点总结

9.1 进程池

代码块
 进程池:
一个池子,里边有固定数量的进程。这些进程一直处于待命状态,一旦有任务来,马上就有进程去处理。
因为在实际业务中,任务量是有多有少的,如果任务量特别的多,不可能要开对应那么多的进程数
开启那么多进程首先就需要消耗大量的时间让操作系统来为你管理它。其次还需要消耗大量时间让
cpu帮你调度它。进程池还会帮程序员去管理池中的进程。
from multiprocessing import Pool   导入进程池
p = Pool(os.cpu_count() + 1)

9.2 进程池有三个方法:

map(func,iterable)函数

代码块
map(func,iterable)
func:进程池中的进程执行的任务函数
iterable: 可迭代对象,是把可迭代对象中的每个元素依次传给任务函数当参数

同步apply(func,args=())

代码块
apply(func,args=()): 同步的效率,也就是说池中的进程一个一个的去执行任务
func:进程池中的进程执行的任务函数
args: 可迭代对象型的参数,是传给任务函数的参数
同步处理任务时,不需要close和join
同步处理任务时,进程池中的所有进程是普通进程(主进程需要等待其执行结束)

apply_async(func,args=(),callback=None)

代码块
apply_async(func,args=(),callback=None): 异步的效率,也就是说池中的进程一次性都去执行任务
 func:进程池中的进程执行的任务函数
args: 可迭代对象型的参数,是传给任务函数的参数
callback: 回调函数,就是说每当进程池中有进程处理完任务了,返回的结果可以交给回调函数,由回调函数进行进一步的处理,回调函数只有异步才有,同步是没有的
异步处理任务时,进程池中的所有进程是守护进程(主进程代码执行完毕守护进程就结束)
异步处理任务时,必须要加上close和join

回调函数

代码块
进程的任务函数的返回值,被当成回调函数的形参接收到,以此进行进一步的处理操作
回调函数是由主进程调用的,而不是子进程,子进程只负责把结果传递给回调函数

进程间通信
你知道的IPC都有哪些?进程间通信
管道,队列,(锁,信号量,事件)

别跑,点个赞再走

相关文章

网友评论

      本文标题:【第53天】python全栈从入门到放弃

      本文链接:https://www.haomeiwen.com/subject/oiwksctx.html