python 多线程 多进程

1.基础概念

将计算机的cpu理解为工厂,但是假定这个工厂的电力有限,一次只能给一个车间供电。
1)进程:看做工厂的一个车间,拥有独立内存。代表cpu所能处理的单个任务,任一时刻,cpu总是运行一个进程,其他进程处于非运行状态。能够运行的多进程的数量一般等于cpu的核数。
2)线程:看做工厂车间的一个工人,可以共享内存,他们可以协同完成一个任务。

以dell latitude 7430为例,他的设备参数为10核 12线程。线程为什么也能用cpu来定义?

2. 为什么要使用多进程?

对比程序:计算8的20次方,sleep 2 秒。
1)使用传统方式完成计算

# 单进程示例程序
import time
import os
def long_time_task():
    print('当前进程:{}'.format(os.getpid()))  #得到当前的进程号
    time.sleep(2)
    print("结果:{}".format(8**20))

if __name__=="__main__":
    print('当前母进程:{}'.format(os.getpid()))
    start=time.time()
    for i in range(2):
        long_time_task()
    end=time.time()
    print("use time{} seconds".format((end-start)))
# 知道了如何得到当前的进程号
# 知道了一段简单的程序如何计算(统计)时间

'''
out:
当前母进程:266156
当前进程:266156
结果:1152921504606846976
当前进程:266156
结果:1152921504606846976
use time4.004450559616089 seconds
'''

2)使用两个进程完成相同的计算

# 多进程显示示例 创建两个进程p1 p2进行并行计算

from multiprocessing import Process
import os
import time

def long_time_task(i):
    print('子进程:{}-任务{}'.format(os.getpid(),i))
    time.sleep(2)
    print('结果:{}'.format(8**20))
if __name__=="__main__":
    print('当前母进程:{}'.format(os.getpid()))
    start=time.time()
    # 创建两个进程
    p1=Process(target=long_time_task,args=(1,))
    p2=Process(target=long_time_task,args=(2,))
    print('等待所有子进程完成。')
    p1.start() # 启动子进程
    p2.start()
    p1.join() #让该进程阻塞,直到调用join的进程终止 这个代码的目的是为了记录进程阻塞的时间 便于时间统计
    p2.join()
    end=time.time()
    print('总共用时{}秒'.format((end-start)))

# 两个进程是完成相同的事情
# 母进程与子进程的关系:母进程是为了调用子进程?
'''
out:
当前母进程:266156
等待所有子进程完成。
子进程:268112-任务1
子进程:268115-任务2
结果:1152921504606846976
结果:1152921504606846976
总共用时2.0291872024536133秒
'''

3. 多进程进阶

3.1 Pool类

满足当进程数量很多时,创建多个进程以提高cpu利用率的需求(管理系统中并发进程的数量)。具体来说,pool类会统一管理进程的数量(提供指定数量的进程供用户使用),当进程池还没有满,用户有需求时,进程池就会创建相应的进程。若进程池满了,用户有需求时,进程池就会告诉用户先等待。

3.2 Queue队列

用于帮助进程间进行数据通讯

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

# 用于写数据的进程
def write(q):
    print('Process to write:{}'.format(os.getgid())) # 将可变变量输入到字符串中
    for value in ['A','B','C']:
        print('Put %s to Queue...'%value) # 占位符 也是用来将变量输入到字符串中
        q.put(value) # 将数据放入队列
        time.sleep(random.random())

# 用于读数据的进程
def read(q):
    print('Process to read:{}'.format(os.getpid()))
    while True:
        value=q.get(True) # 从队列中取出想要的数据 只能强行终止
        print('Get %s from queue'% value)

# 主进程调用程序:创建队列 创建读写进程 调用读写进程
if __name__ =="__main__":
    # 父进程创建Queue 传给各个子进程
    q=Queue()
    pw=Process(target=write,args=(q,))
    pr=Process(target=read,args=(q,))
    pw.start()
    pr.start()
    pw.join() # 阻塞 等待程序完成
    pr.terminate() # 只能强行终止??

'''
out:
Process to write:1004
Put A to Queue...
Process to read:268281
Get A from queue
Put B to Queue...
Get B from queue
Put C to Queue...
Get C from queue
'''

参考文档

【1】官方文档
【2】知乎推文

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值