资讯专栏INFORMATION COLUMN

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

ivydom / 2148人阅读

摘要:概述最近需要在一个基于的服务中集成遇到了一个带来的兼容性问题测试代码如下当对模块之后进程卡在了只有按中断该线程之后程序才继续运行但如果不对进行线程之后程序继续运行这是为什么呢分析使用进行调试分为两种情况对进行程序在之后切换到运行似乎就切换不

概述

最近需要在一个基于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


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

2. 不对thread进行patch

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

结论

可见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的底层并发模式时, 请三思.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41359.html

相关文章

  • 比较了Gruvi针对asyncio,gevent和eventlet一些设计决策和功能

    下表比较了Gruvi针对asyncio,gevent和eventlet的一些设计决策和功能。 * 特征 Gruvi Asyncio Gevent Eventlet IO library(依赖包) libuv stdlib libev stdlib / libevent IO abstractionTransports/Protocols Transports/ProtocolsGre...

    ls0609 评论0 收藏0
  • 基于websocketcelery任务状态监控

    摘要:目的曾经想向前台实时返回任务的状态监控,也查看了很多博客,但是好多也没能如愿,因此基于网上已有的博客已经自己的尝试,写了一个小的,实现前台实时获取后台传输的任务状态。实现仿照其他例子实现了一个简单的后台任务监控。 1. 目的曾经想向前台实时返回Celery任务的状态监控,也查看了很多博客,但是好多也没能如愿,因此基于网上已有的博客已经自己的尝试,写了一个小的demo,实现前台实时获取后...

    microelec 评论0 收藏0
  • 老生常谈闭包(你不可不知若干知识点)

    摘要:闭包是什么这是一个在面试的过程中出现的概率为以上的问题,也是我们张口就来的问题。文章推荐我们面试中在被问到闭包这个问题是要注意的几点闭包的延伸,让面试变得 闭包是什么?这是一个在面试的过程中出现的概率为60%以上的问题,也是我们张口就来的问题。但是我们往往发现,在面试的过程中我们的回答并不那么让面试官满意,我们虽然能张口说出一些但是却不能系统的对这个问题进行回答。面试官希望加入自己团队...

    daydream 评论0 收藏0
  • 通过demo学习OpenStack开发所需基础知识 -- API服务(2)

    摘要:这种表示具体的。中其他的关键字则是函数的参数,用于表示不同的前缀。这个是这个指定的第一个,作用是限制请求的大小。表示实现主要功能的应用,是一个标准的。对象是根据中的配置来处理的。最后会把请求交给进行处理。 本文会重点讲解OpenStack中使用的API开发框架的使用。但是本文的目的并不是覆盖这些框架的使用细节,而是通过说明重要的部分,降低初学者的入门的门槛。框架的使用细节都可以从文档中...

    Martin91 评论0 收藏0
  • 通过demo学习OpenStack开发所需基础知识 -- API服务(1)

    摘要:通过,也就是通过各个项目提供的来使用各个服务的功能。通过使用的方式是由各个服务自己实现的,比如负责计算的项目实现了计算相关的,负责认证的项目实现了认证和授权相关的。的服务都是使用的方式来部署的。 使用OpenStack服务的方式 OpenStack项目作为一个IaaS平台,提供了三种使用方式: 通过Web界面,也就是通过Dashboard(面板)来使用平台上的功能。 通过命令行,也就...

    Jason_Geng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<