python基础⑭-进程池、线程池、协程

系列文章目录


python基础①-基础环境搭建和工具使用
python基础②-常用的各种数据类型初认知
python基础③-数据类型常用的操作和方法字符串、数值、bool
python基础④-数据类型常用的操作和方法列表、元组、字典、集合
python基础⑤-控制流程
python基础⑥-函数
python基础⑦-字符编码与文件操作
python基础⑧-异常
python基础⑨-迭代器和生成器
python基础⑩-面向对象
python基础⑪-继承与派生
python基础⑫-多进程
python基础⑬-多线程
python基础⑭-进程池、线程池、协程
python基础⑮-网络编程socket
python基础⑯-网络编程socket进阶

为什么要有进程池和线程池?
开辟进程线程比较耗费资源。那些已经执行完任务的进程和线程不应该被关闭。而是应该利用起来给别的任务执行使用

进程池

计算机开进程或者线程受限于计算机本身的硬件,所以就有了进程池和线程池限制最大进程或者线程数
不会造新的进程或者线程,不会浪费内存空间

提交任务的两种方式:

同步调用:提交完一个任务之后,就在原地等待,等待任务完完整整地运行完毕拿到结果后,再执行下一行代码,会导致任务是串行执行的
提交任务的方法,串行是任务的运行状态

异步调用:提交完一个任务之后,不在原地等待,结果???,而是直接执行下一行代码,会导致任务是并发执行的

future.result() 会阻塞当前线程。当提交的任务执行完了才会解除阻塞并获取结果。异步提交其实就是一股脑先提交。最后一把获取结果


from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time, os, random


def task(name):
    print('%s%s is running' % (name, os.getpid()))
    time.sleep(random.randint(1, 3))
    return 123


if __name__ == '__main__':
    print(os.cpu_count())
    # 不写就是自己cpu的核数
    # 不写就是自己cpu的核数
    p = ProcessPoolExecutor(4)
    # 只会开4个进程的id
    for i in range(20):
        # p.submit(task,'进程pid')
        # 返回值
        future = p.submit(task, '进程pid')
        # print(future)
        # 同步调用
        print(future.result())
    print('主')
    # 异步提交
    l = []
    for i in range(10):
        # p.submit(task,'进程pid')
        # 返回值
        future = p.submit(task, '进程pid')
        # print(future)
        # 同步调用
        l.append(future)
        # print(future.result())

    # #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕
    p.shutdown(wait=True)
    for future in l:
        # 一次性全部拿到结果
        print(future.result())
    print('主')

线程池

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from threading import Thread, Lock, currentThread
import time, os, random


def task(name):
    thread = currentThread()
    print('%s%s is running' % (name, thread.ident))
    time.sleep(random.randint(1, 3))
    return 123


if __name__ == '__main__':
    print(os.cpu_count())
    p = ThreadPoolExecutor()
    for i in range(20):
        # p.submit(task,'线程标识')
        # 返回值
        future = p.submit(task, '线程标识')
        print(future)
        # 同步调用
        print(future.result())
    print('主')
    # 异步提交
    l = []
    for i in range(10):
        # p.submit(task,'线程标识')
        # 返回值
        future = p.submit(task, '线程标识')
        # print(future)
        # 同步调用
        l.append(future)
        # print(future.result())

    # #关闭进程池的入口,并且在原地等待进程池内所有任务运行完毕
    p.shutdown(wait=True)
    for future in l:
        # 一次性全部拿到结果
        print(future.result())
    print('主')

协程

在线程下实现并发
操作系统认为最小单位是线程
并发(多个任务看起来是同时执行就是并发):切换+保存状态(操作系统)
多线程是多个线程,线程在一个进程里面,线程之间切换,整个程序
多进程其实也是多个线程,线程分散到不同进程里面了,进程之间切换,整个程序
线程遇到io阻塞
应用程序级别来控制切换多个任务
遇到io操作切换才有意义
协程
协程是单线程实现并发,又称微线程
注意:协程是程序员想象出来的东西,操作系统里只有进程和线程的概念(操作系统调度的是线程)
在单线程下实现多个任务间遇到IO就切换就可以降低单线程的IO时间,从而最大限度地提升单线程的效率
没有遇到io切换会降低效率
遇到io切换会增加效率
链接循环和通信循环,并没有解决单线程下的io问题
协程可以把单个线程的效率最高

简单来说就是协程就是为了进一步避免遇到io操作时,多线程切换导致的资源损耗。遇到io操作时。在同一个线程里面的协程来切换。这是代码逻辑上的切换。不涉及操作系统。所以性能很高

# 安装模块
# pip install gevent
# 1.必须要放到文件的开头
# 打标记
from gevent import monkey

# 所有的io行为进行打包
monkey.patch_all()
# 导入gevent管理的任务
from gevent import spawn, joinall

import time


def play(name):
    print('%s play 1' % name)
    time.sleep(5)
    print('%s play 2' % name)


def eat(name):
    print('%s eat 1' % name)
    time.sleep(3)
    print('%s eat 2' % name)


start = time.time()
# 异步提交任务,不管结果,直接运行下行代码
g1 = spawn(play, '小王')
g2 = spawn(eat, '小戴')
# g1.join()
# g2.join()
# 一行代码搞定
joinall([g1, g2])
# 不同的python版本可能不一样。我用的 3.9版本主线程会等待所有协程执行完才会关闭
# time.sleep(4)
# 线程死了没了
print('主', time.time() - start)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七层汉堡王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值