一、问题描述

在Django视图函数中,导入 gevent 模块

  1. import gevent
  2. from gevent import monkey; monkey.patch_all()
  3. from gevent.pool import Pool

启动Django报错:

  1. MonkeyPatchWarning: Monkey-patching outside the main native thread. Some APIs will not be available. Expect a KeyError to be printed at shutdown.
  2. from gevent import monkey; monkey.patch_all()
  3. MonkeyPatchWarning: Monkey-patching not on the main thread; threading.main_thread().join() will hang from a greenlet
  4. from gevent import monkey; monkey.patch_all()

原因在于执行这行 monkey.patch_all() 代码时报错了。

既然Django不能使用协程,那我需要使用异步执行,怎么办?

请看下文

二、进程池、线程池与异步调用、回调机制

进程池、线程池使用案例

进程池与线程池使用几乎相同,只是调用模块不同~!!

  1. from concurrent.futures import ProcessPoolExecutor # 进程池模块
  2. from concurrent.futures import ThreadPoolExecutor # 线程池模块
  3. import os, time, random
  4.  
  5. # 下面是以进程池为例, 线程池只是模块改一下即可
  6. def talk(name):
  7. print('name: %s pis%s run' % (name,os.getpid()))
  8. time.sleep(random.randint(1, 3))
  9.  
  10. if __name__ == '__main__':
  11. pool = ProcessPoolExecutor(4) # 设置线程池大小,默认等于cpu核数
  12. for i in range(10):
  13. pool.submit(talk, '进程%s' % i) # 异步提交(只是提交需要运行的线程不等待)
  14.  
  15. # 作用1:关闭进程池入口不能再提交了 作用2:相当于jion 等待进程池全部运行完毕
  16. pool.shutdown(wait=True)
  17. print('主进程')

异步调用与同步调用

concurrent.futures模块提供了高度封装的异步调用接口 
ThreadPoolExecutor:线程池,提供异步调用 
ProcessPoolExecutor: 进程池,提供异步调用

同步调用

  1. from concurrent.futures import ProcessPoolExecutor # 进程池模块
  2. import os, time, random
  3.  
  4. # 1、同步调用: 提交完任务后、就原地等待任务执行完毕,拿到结果,再执行下一行代码(导致程序串行执行)
  5. def talk(name):
  6. print('name: %s pis%s run' % (name,os.getpid()))
  7. time.sleep(random.randint(1, 3))
  8.  
  9. if __name__ == '__main__':
  10. pool = ProcessPoolExecutor(4)
  11. for i in range(10):
  12. pool.submit(talk, '进程%s' % i).result() # 同步迪奥用,result(),相当于join 串行
  13.  
  14. pool.shutdown(wait=True)
  15. print('主进程')

异步调用

  1. from concurrent.futures import ProcessPoolExecutor # 进程池模块
  2. import os, time, random
  3.  
  4. def talk(name):
  5. print('name: %s pis%s run' % (name,os.getpid()))
  6. time.sleep(random.randint(1, 3))
  7.  
  8. if __name__ == '__main__':
  9. pool = ProcessPoolExecutor(4)
  10. for i in range(10):
  11. pool.submit(talk, '进程%s' % i) # 异步调用,不需要等待
  12.  
  13. pool.shutdown(wait=True)
  14. print('主进程')

回调机制

可以为进程池或线程池内的每个进程或线程绑定一个函数,该函数在进程或线程的任务执行完毕后自动触发,并接收任务的返回值当作参数,该函数称为回调函数

  1. #parse_page拿到的是一个future对象obj,需要用obj.result()拿到结果
  2. p.submit(这里异步调用).add_done_callback(方法)

案例:下载解析网页页面

  1. import time
  2. import requests
  3. from concurrent.futures import ThreadPoolExecutor # 线程池模块
  4.  
  5. def get(url):
  6. print('GET %s' % url)
  7. response = requests.get(url) # 下载页面
  8. time.sleep(3) # 模拟网络延时
  9. return {'url': url, 'content': response.text} # 页面地址和页面内容
  10.  
  11. def parse(res):
  12. res = res.result() # !取到res结果 【回调函数】带参数需要这样
  13. print('%s res is %s' % (res['url'], len(res['content'])))
  14.  
  15. if __name__ == '__main__':
  16. urls = {
  17. 'http://www.baidu.com',
  18. 'http://www.360.com',
  19. 'http://www.iqiyi.com'
  20. }
  21.  
  22. pool = ThreadPoolExecutor(2)
  23. for i in urls:
  24. pool.submit(get, i).add_done_callback(parse) # 【回调函数】执行完线程后,跟一个函数

本文参考链接:

https://blog.csdn.net/weixin_42329277/article/details/80741589

Python Django 协程报错,进程池、线程池与异步调用、回调机制的更多相关文章

  1. 协程与concurent.furtrue实现线程池与进程池

    1concurent.furtrue实现线程池与进程池 2协程 1concurent.furtrue实现线程池与进程池 实现进程池 #进程池 from concurrent.futures impor ...

  2. Swoole协程报错 Uncaught Error: Call to undefined function go()

    解决方法, 在PHP.ini中开启短名

  3. concurrent.futures模块 -----进程池 ---线程池 ---回调

    concurrent.futures模块提供了高度封装的异步调用接口,它内部有关的两个池 ThreadPoolExecutor:线程池,提供异步调用,其基础就是老版的Pool ProcessPoolE ...

  4. python并发编程-进程池线程池-协程-I/O模型-04

    目录 进程池线程池的使用***** 进程池/线程池的创建和提交回调 验证复用池子里的线程或进程 异步回调机制 通过闭包给回调函数添加额外参数(扩展) 协程*** 概念回顾(协程这里再理一下) 如何实现 ...

  5. Python进阶(5)_进程与线程之协程、I/O模型

    三.协程 3.1协程概念 协程:又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存 ...

  6. Python 原生协程------asyncio

    协程 在python3.5以前,写成的实现都是通过生成器的yield from原理实现的, 这样实现的缺点是代码看起来会很乱,于是3.5版本之后python实现了原生的协程,并且引入了async和aw ...

  7. python之协程与IO操作

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B ...

  8. python的协程和_IO操作

    协程Coroutine: 协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行. 注意,在一个子程序中中断,去执行其他子程序,不是函数调用,有点 ...

  9. python 3 协程函数

    python 3 协程函数 1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器 2:与return功能类似,都可以返回值,但不同的是,return只能返回一次值,而yiel ...

随机推荐

  1. 如何学习uni-app?

    uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架. 开发者通过编写 Vue.js 代码,uni-app 将其编译到iOS.Android.微信小程序.H5等多个平台,保证其正确运行并 ...

  2. Zuul超时配置

    在实际运用过程中,发现有时候zuul的第一次请求经常会超时.不知道你们怎样,我经常在重启zuul后,第一次访问经常会出现超时现象,但是第二次访问就不会了. 第一次经常超时 这是因为zuul采用了懒加载 ...

  3. 查看服务器内存、CPU、网络等占用情况的命令--汇总

    搭建测试环境过程中,需要对正在使用的aws服务器(实际这是一台虚拟出来的服务器),查看它在运行脚本,启动脚本时的内存,CPU,网络等使用情况 1.查看服务器cpu内核个数: -cat 每个物理cpu中 ...

  4. mysql rtrim() 函数

    mysql> select rtrim(" cdcdcd "); +--------------------+ | rtrim(" cdcdcd ") | ...

  5. Mac版微信无法安装之始末

    前言 Mac版微信安装不了...纠结了一周时间 ̄□ ̄||... 今天终于可以登录了(虽然还是没有安装到电脑上,但可以使用了) 因为之前也查了很多,有人遇到,但是没有可以解决我这个问题的方法, 浪费了很 ...

  6. 第06组 Alpha事后诸葛亮

    一.组长博客: https://www.cnblogs.com/mhq-mhq/p/11923194.html 二.Postmortem模板 设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚 ...

  7. python3.6安装 zipimport.ZipImportError: can't decompress data; zlib not available【转】

    python3.6.3 安装: .tgz cd Python- ./configure make make altinstall `make altinstall` , 报错: zipimport.Z ...

  8. C语言函数sscanf()的用法-从字符串中读取与指定格式相符的数据(转)

    C语言函数sscanf()的用法 sscanf() - 从一个字符串中读进与指定格式相符的数据. 函数原型: int sscanf( string str, string fmt, mixed var ...

  9. oracle 19c jdbc之Reactive Streams Ingestion (RSI) Library

    19c jdbc新特性 https://blogs.oracle.com/dev2dev/whats-new-in-193-and-183-jdbc-and-ucp jdbc实现直接路径加载 http ...

  10. java开源工具包-Jodd框架

    java开源工具包-Jodd框架 /    2019-07-24 Jodd是一个Java工具包和微型框架,Jodd 工具包含一些实用的工具类和小型框架,增强了 JDK 提供很多强大的功能,可以帮助实现 ...