专栏首页python3Python Django 协程报错,进程池、线程池与异步调用、回调机制

Python Django 协程报错,进程池、线程池与异步调用、回调机制

一、问题描述

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

import gevent
from gevent import monkey; monkey.patch_all()
from gevent.pool import Pool

启动Django报错:

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

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

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

请看下文

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

进程池、线程池使用案例

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

from concurrent.futures import ProcessPoolExecutor  # 进程池模块
from concurrent.futures import ThreadPoolExecutor  # 线程池模块
import os, time, random

#  下面是以进程池为例, 线程池只是模块改一下即可
def talk(name):
    print('name: %s  pis%s  run' % (name,os.getpid()))
    time.sleep(random.randint(1, 3))

if __name__ == '__main__':
    pool = ProcessPoolExecutor(4)  # 设置线程池大小,默认等于cpu核数
    for i in range(10):
        pool.submit(talk, '进程%s' % i)  # 异步提交(只是提交需要运行的线程不等待)

    # 作用1:关闭进程池入口不能再提交了   作用2:相当于jion 等待进程池全部运行完毕
    pool.shutdown(wait=True)  
    print('主进程')

异步调用与同步调用

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

同步调用

from concurrent.futures import ProcessPoolExecutor  # 进程池模块
import os, time, random


# 1、同步调用: 提交完任务后、就原地等待任务执行完毕,拿到结果,再执行下一行代码(导致程序串行执行)
def talk(name):
    print('name: %s  pis%s  run' % (name,os.getpid()))
    time.sleep(random.randint(1, 3))

if __name__ == '__main__':
    pool = ProcessPoolExecutor(4)
    for i in range(10):
        pool.submit(talk, '进程%s' % i).result()  # 同步迪奥用,result(),相当于join 串行

    pool.shutdown(wait=True)
    print('主进程')

异步调用

from concurrent.futures import ProcessPoolExecutor  # 进程池模块
import os, time, random

def talk(name):
    print('name: %s  pis%s  run' % (name,os.getpid()))
    time.sleep(random.randint(1, 3))

if __name__ == '__main__':
    pool = ProcessPoolExecutor(4)
    for i in range(10):
        pool.submit(talk, '进程%s' % i)  # 异步调用,不需要等待

    pool.shutdown(wait=True)
    print('主进程')

回调机制

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

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

案例:下载解析网页页面

import time
import requests
from concurrent.futures import ThreadPoolExecutor  # 线程池模块

def get(url):
    print('GET %s' % url)
    response = requests.get(url)  # 下载页面
    time.sleep(3)  # 模拟网络延时
    return {'url': url, 'content': response.text}  # 页面地址和页面内容

def parse(res):
    res = res.result()  # !取到res结果 【回调函数】带参数需要这样
    print('%s res is %s' % (res['url'], len(res['content'])))

if __name__ == '__main__':
    urls = {
        'http://www.baidu.com',
        'http://www.360.com',
        'http://www.iqiyi.com'
    }

    pool = ThreadPoolExecutor(2)
    for i in urls:
        pool.submit(get, i).add_done_callback(parse)  # 【回调函数】执行完线程后,跟一个函数

本文参考链接:

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 进程池、线程池、回调函数、协程

      也就是说,硬件的承载能力是有限度的,在保证高效率工作的同时应该还需要保证硬件的资源占用情况,所以需要给硬件设置一个上限来减轻硬件的压力,所以就有了池的概念。

    py3study
  • curl 支持 HTTP2

    首先使用 curl 请求 https://nghttp2.org(使用了 http2)。但是结果却是返回了 HTTP1.1 响应:

    py3study
  • python-daemon日志记录的一个

    最近用到了python-daemon这个库来使一个进程成为daemon进程,代码大致如下:

    py3study
  • 通配符匹配

    给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。

    你的益达
  • MessagePack Java 0.6.X 使用一个消息打包(message-packable)类

    使用注解 @Message 来让你可以序列化你自己类中对象的 public 字段。

    HoneyMoose
  • MessagePack Java 0.6.X 使用一个消息打包(message-packable)类

    使用注解 @Message 来让你可以序列化你自己类中对象的 public 字段。

    HoneyMoose
  • 「走进k8s」Kubernetes1.15.1的持久化存储StorageClass(32)

    1.自动创建的 PV 以${namespace}-${pvcName}-${pvName}这样的命名格式创建在 NFS 服务器上的共享数据目录中。2.而当这个 ...

    IT故事会
  • 让MyBatis Generator产生的Mapper更简洁

    比如,我们建立两个测试表,一个是t_user, 一个是t_news。其建表语句如下:

    孟君
  • SpringBoot整合elasticsearch

    dalaoyang
  • 快来看,敖丙还不会curl

    curl应该还算是一个比较常见的东西吧?比如说,我们在学习Elasticsearch的时候去看官方文档,就可以看到curl的踪影,有的时候看别人的写的文档也会看...

    Java3y

扫码关注云+社区

领取腾讯云代金券