eventlet 之 monkeypatch 带来的若干兼容性问题实例分析

news/2024/12/23 13:19:52 标签: python, 数据库

概述

最近需要在一个基于nameko/eventlet的服务中集成grpc client, 遇到了一个monkeypatch带来的兼容性问题, 测试代码如下:

import eventlet

eventlet.monkey_patch(thread=True)

import threading

from grpc._cython import cygrpc


class TestThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        completion_queue = cygrpc.CompletionQueue()
        while True:
            _ = completion_queue.poll()


threading._VERBOSE = True
t = TestThread()
t.start()

print('if thread is not patched, this message will be printed')

当对thread模块patch之后, 进程卡在了t.start(), 只有按ctrl+c中断该线程之后, 程序才继续运行. 但如果不对thread进行patch, 线程start之后, 程序继续运行. 这是为什么呢?

分析

使用pdb进行调试, 分为两种情况:

1. 对thread进行patch

clipboard.png
程序在switch之后切换到TestThread运行, 似乎就切换不回到主线程了!按下ctrl+c后TestThread才中断, 并在主线程继续运行.

2. 不对thread进行patch

在TestThread进入start之后, self.__started.wait()直接返回, 值得注意的是, 在start内部调用_start_new_thread就直接启动子线程, 并且直接返回了!
clipboard.png

结论

可见monkeypatch修改了threading标准库中的_start_new_thread方法, Condition类等. 当patch之后,_start_new_thread方法并不直接启动线程, 而是返回一个greenlet, 在这个问题当中, grpc调用的是一个c extension中的threading pool, monkeypatch无法对这个extension进行patch, 导致了后来switch到这个greenlet中时其实是进入到另一个线程中. 因为greenlet无法在不同的线程中切换, 导致程序无法从TestThread切回来, 只有主动去中断TestThread, 才能被恢复.
自从遇到了这个问题, 以后做项目的并发模型就更加慎重了:). 如果不清楚monkeypatch到底做了些什么, 在选择协程做python的底层并发模式时, 请三思.


http://www.niftyadmin.cn/n/1122883.html

相关文章

如何估算代码量_如何跟踪SEO进度并衡量SEO结果?

您如何跟踪SEO进度并衡量SEO结果?关于该主题的大部分内容都集中在跟踪正确的指标上。很容易找到您应该跟踪的SEO指标和KPI列表(通常很长),但是指标实际上仅是跟踪SEO进度的表面。例如,关键词排名是搜索引擎优化专家的常用指标。不要误会我们的…

简单认识一下Vuejs

简单认识一下VuejsVuejs 是什么Vue是一个渐进式的框架,什么是渐进式的呢?Vue有很多特点和Web开发中常见的高级功能什么是MVVM?Vuejs安装流程学习开发工具:webstorm、vscode在vs code开发工具中安装扩展:Live ServerVuejs 是什么 …

【Silverlight】Bing Maps学习系列(七):使用Bing Maps的图片系统(Tile System)

目前包括微软必应地图在内的几乎所有在线电子地图(如:Google Maps等)都事先对地图图片(Tile)进行预处理,通过特定的算法将预处理过后的图片进行无缝的拼接,建立一套统一有规律、标准的地图映射系统。Bing Maps地图映射…

python实现isprime函数_Python参数类型以及实现isOdd函数,isNum函数,multi函数,isPrime函数...

Python参数类型以及实现isOdd函数,isNum函数,multi函数,isPrime函数一、Python参数类型形参:定义函数时的参数变量。实参:调用函数时使用的参数变量。参数传递的过程,就是把实参的引用传递给形参&#xff0…

asp.net页面刷新或者回发后DIV的滚动条位置不变!(转)

源文件:http://www.cnblogs.com/nyth/archive/2011/06/10/2077868.html 当把数据放在div里面,然后给div设置Scroll显示,在页面刷新后或者是处理了某个按钮的事件,这个时候div的滚动轴就会又回到起始位置,但事实上得把数…

MyEclipse移动开发教程:构建MobiOne应用(六)

2019独角兽企业重金招聘Python工程师标准>>> 【中文网周年庆】MyEclipse个人开发者专享8折!在线订购>> 在上文中,小编主要为大家介绍了如何配置应用详细信息、图标和Splash Screen。在本文中,我们将继续为大家介绍如何构建应…

00-Vue初体验

Vue初体验 体验Vue的响应式(数据发生改变,页面会自动跟着改变) 我们做了什么事情 在阅读JavaScript代码是,会发现创建了一个Vue对象。创建Vue对象的时候,传入了一些options:{} 1.{}中包含了el属性:该属性…

重定向到登录在SharePoint 2007

从一家英文网站上找到的资料,翻译过来了: 如果您需要确保在用户登录之前在MOSS访问您的自定义,然后重定向回登录后,您可以使用一个方法,如内置如下: Microsoft.SharePoint.Utilities.SPUtility.EnsureAuthe…