摘要:概述最近需要在一個(gè)基于的服務(wù)中集成遇到了一個(gè)帶來(lái)的兼容性問(wèn)題測(cè)試代碼如下當(dāng)對(duì)模塊之后進(jìn)程卡在了只有按中斷該線程之后程序才繼續(xù)運(yùn)行但如果不對(duì)進(jìn)行線程之后程序繼續(xù)運(yùn)行這是為什么呢分析使用進(jìn)行調(diào)試分為兩種情況對(duì)進(jìn)行程序在之后切換到運(yùn)行似乎就切換不
概述
最近需要在一個(gè)基于nameko/eventlet的服務(wù)中集成grpc client, 遇到了一個(gè)monkeypatch帶來(lái)的兼容性問(wèn)題, 測(cè)試代碼如下:
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")
當(dāng)對(duì)thread模塊patch之后, 進(jìn)程卡在了t.start(), 只有按ctrl+c中斷該線程之后, 程序才繼續(xù)運(yùn)行. 但如果不對(duì)thread進(jìn)行patch, 線程start之后, 程序繼續(xù)運(yùn)行. 這是為什么呢?
分析使用pdb進(jìn)行調(diào)試, 分為兩種情況:
1. 對(duì)thread進(jìn)行patch
程序在switch之后切換到TestThread運(yùn)行, 似乎就切換不回到主線程了!按下ctrl+c后TestThread才中斷, 并在主線程繼續(xù)運(yùn)行.
在TestThread進(jìn)入start之后, self.__started.wait()直接返回, 值得注意的是, 在start內(nèi)部調(diào)用_start_new_thread就直接啟動(dòng)子線程, 并且直接返回了!
可見(jiàn)monkeypatch修改了threading標(biāo)準(zhǔn)庫(kù)中的_start_new_thread方法, Condition類等. 當(dāng)patch之后,_start_new_thread方法并不直接啟動(dòng)線程, 而是返回一個(gè)greenlet, 在這個(gè)問(wèn)題當(dāng)中, grpc調(diào)用的是一個(gè)c extension中的threading pool, monkeypatch無(wú)法對(duì)這個(gè)extension進(jìn)行patch, 導(dǎo)致了后來(lái)switch到這個(gè)greenlet中時(shí)其實(shí)是進(jìn)入到另一個(gè)線程中. 因?yàn)間reenlet無(wú)法在不同的線程中切換, 導(dǎo)致程序無(wú)法從TestThread切回來(lái), 只有主動(dòng)去中斷TestThread, 才能被恢復(fù).
自從遇到了這個(gè)問(wèn)題, 以后做項(xiàng)目的并發(fā)模型就更加慎重了:). 如果不清楚monkeypatch到底做了些什么, 在選擇協(xié)程做python的底層并發(fā)模式時(shí), 請(qǐng)三思.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/41359.html
下表比較了Gruvi針對(duì)asyncio,gevent和eventlet的一些設(shè)計(jì)決策和功能。 * 特征 Gruvi Asyncio Gevent Eventlet IO library(依賴包) libuv stdlib libev stdlib /?libevent IO abstractionTransports/Protocols Transports/ProtocolsGre...
摘要:目的曾經(jīng)想向前臺(tái)實(shí)時(shí)返回任務(wù)的狀態(tài)監(jiān)控,也查看了很多博客,但是好多也沒(méi)能如愿,因此基于網(wǎng)上已有的博客已經(jīng)自己的嘗試,寫了一個(gè)小的,實(shí)現(xiàn)前臺(tái)實(shí)時(shí)獲取后臺(tái)傳輸?shù)娜蝿?wù)狀態(tài)。實(shí)現(xiàn)仿照其他例子實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的后臺(tái)任務(wù)監(jiān)控。 1. 目的曾經(jīng)想向前臺(tái)實(shí)時(shí)返回Celery任務(wù)的狀態(tài)監(jiān)控,也查看了很多博客,但是好多也沒(méi)能如愿,因此基于網(wǎng)上已有的博客已經(jīng)自己的嘗試,寫了一個(gè)小的demo,實(shí)現(xiàn)前臺(tái)實(shí)時(shí)獲取后...
摘要:閉包是什么這是一個(gè)在面試的過(guò)程中出現(xiàn)的概率為以上的問(wèn)題,也是我們張口就來(lái)的問(wèn)題。文章推薦我們面試中在被問(wèn)到閉包這個(gè)問(wèn)題是要注意的幾點(diǎn)閉包的延伸,讓面試變得 閉包是什么?這是一個(gè)在面試的過(guò)程中出現(xiàn)的概率為60%以上的問(wèn)題,也是我們張口就來(lái)的問(wèn)題。但是我們往往發(fā)現(xiàn),在面試的過(guò)程中我們的回答并不那么讓面試官滿意,我們雖然能張口說(shuō)出一些但是卻不能系統(tǒng)的對(duì)這個(gè)問(wèn)題進(jìn)行回答。面試官希望加入自己團(tuán)隊(duì)...
摘要:這種表示具體的。中其他的關(guān)鍵字則是函數(shù)的參數(shù),用于表示不同的前綴。這個(gè)是這個(gè)指定的第一個(gè),作用是限制請(qǐng)求的大小。表示實(shí)現(xiàn)主要功能的應(yīng)用,是一個(gè)標(biāo)準(zhǔn)的。對(duì)象是根據(jù)中的配置來(lái)處理的。最后會(huì)把請(qǐng)求交給進(jìn)行處理。 本文會(huì)重點(diǎn)講解OpenStack中使用的API開(kāi)發(fā)框架的使用。但是本文的目的并不是覆蓋這些框架的使用細(xì)節(jié),而是通過(guò)說(shuō)明重要的部分,降低初學(xué)者的入門的門檻??蚣艿氖褂眉?xì)節(jié)都可以從文檔中...
摘要:通過(guò),也就是通過(guò)各個(gè)項(xiàng)目提供的來(lái)使用各個(gè)服務(wù)的功能。通過(guò)使用的方式是由各個(gè)服務(wù)自己實(shí)現(xiàn)的,比如負(fù)責(zé)計(jì)算的項(xiàng)目實(shí)現(xiàn)了計(jì)算相關(guān)的,負(fù)責(zé)認(rèn)證的項(xiàng)目實(shí)現(xiàn)了認(rèn)證和授權(quán)相關(guān)的。的服務(wù)都是使用的方式來(lái)部署的。 使用OpenStack服務(wù)的方式 OpenStack項(xiàng)目作為一個(gè)IaaS平臺(tái),提供了三種使用方式: 通過(guò)Web界面,也就是通過(guò)Dashboard(面板)來(lái)使用平臺(tái)上的功能。 通過(guò)命令行,也就...
閱讀 3244·2021-09-07 10:10
閱讀 3587·2019-08-30 15:44
閱讀 2590·2019-08-30 15:44
閱讀 3014·2019-08-29 15:11
閱讀 2231·2019-08-28 18:26
閱讀 2753·2019-08-26 12:21
閱讀 1120·2019-08-23 16:12
閱讀 3037·2019-08-23 14:57