Python多进程

1.多进程的目的还是为了提升cpu的处理效率

  • multiprocessing
    • Process
      • start 启动进程  
      • join  等待进程结束
  • 案例一. 对列表分段求和

  1. 采用多进程

  • from multiprocessing import Process ,Pool 
    import time
    import os  
    import sys 
    sys.path.append("/mnthis/qihao.huang/tools/") 
    from utils import *  
    
    
    def test(x,start,end):
        # x为一个list 
        return sum(x[start:end])
    
    print(get_now())
    x=list(range(400000000))
    p1=Process(target=test,args=(x,0,100000000,))
    p2=Process(target=test,args=(x,100000000,200000000,))
    p3=Process(target=test,args=(x,200000000,300000000,))
    p4=Process(target=test,args=(x,300000000,400000000,))
    p1.start()    #启动进程
    p2.start() 
    p3.start() 
    p4.start() 
    p1.join() ##等待所有的子进程执行结束, 再执行主进程
    p2.join() 
    p3.join()
    p4.join() 
    print(get_now())   
    

    输出: 

  • 2022-03-23 02:08:14

  • 2022-03-23 02:11:59     只需要3分45秒 

2.不采用多进程,顺序执行

print(get_now())
test(x,0,100000000)
test(x,100000000,20000000)
test(x,200000000,300000000)
test(x,300000000,400000000)
print(get_now())

        输出:

        2022-03-23 02:12:00
        2022-03-23 02:25:59 需要13分59秒

2.如果管理很多个进程,怎么办?通过进程池来

  • multiprocessing
    • Pool  进程池 
      • apply 阻塞
      • apply_async 非阻塞

案例二. 进程池如何管理

1.非阻塞方式,采用apply_async

# 定义睡觉(sj)函数 
def sj(x):
    time.sleep(x) 


print(get_now())
pool=Pool(processes=4)  # 维持4个,
for i in [1,2,3,4,5,6]:
    pool.apply_async(sj,args=(i,))
pool.close()   # 不让新的进程进来的 
pool.join() 
print(get_now())

        输出:

2022-03-23 03:24:26
2022-03-23 03:24:34 需要8秒,为什么是8秒?下面进行分析下

# 第1秒  进程1结束,进程5进去
# 第2秒,进程2结束,进程6进去
# 第3秒,进程3结束
# 第4秒,进程4结束
# 第5秒,
# 第6秒,进程5结束
# 第7秒
# 第8秒,进程6结束

2.阻塞方式,需要多少秒?21秒(1+2+3+4+5+6)

# 进程池的方式
print(get_now())
pool=Pool(processes=4)  # 维持4个,
for i in [1,2,3,4,5,6]:
    pool.apply(sj,args=(i,))
pool.close()   # 不让新的进程进来的 
pool.join() 
print(get_now())

案例三. 子进程的结果如何拿到

  • 调用get() 方法即可 
import pandas  as pd 
pool=Pool(processes=4) 

result=pd.DataFrame()
for ele in [[1,2],[2,3],[3,4]]:
    result=pd.concat([result,pool.apply_async(get_data,args=(ele,)).get()],axis=1)
pool.close()   # 不让新的进程进来的 
pool.join() 
print(get_now()) 

print(result)

案例四.map方式执行进程池,

        其实就是把for循环改成map,直接返回List

import pandas  as pd 
pool=Pool(processes=cpu_count()) 

pool.map(get_data,[[1,2],[2,3],[3,4]])

3.针对同一份数据,并发会不会引起数据的混乱?

用Lock,即锁的方式进行解决

# 不加锁的方式

def getList(L,i):
    print(L[:i])


if __name__ == '__main__':   
    ll=["1","2","3","4","5"]
    manager = multiprocessing.Manager().Lock()
    pool=Pool(processes=cpu_count())
    for i in range(5):
        pool.apply_async(getList,args=(ll,i,))

    pool.close()   # 不让新的进程进来的 
    pool.join() 

# 加锁的方式,其实会串行执行

def getList(L,i,lock):
    lock.acquire()
    print(L[:i])
    lock.release()


if __name__ == '__main__':   
    ll=["1","2","3","4","5"]
    manager = multiprocessing.Manager().Lock()
    pool=Pool(processes=cpu_count())
    for i in range(5):
        pool.apply_async(getList,args=(ll,i,lock,))

    pool.close()   # 不让新的进程进来的 
    pool.join() 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值