精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

聊一聊 C# 前臺線程如何阻塞程序退出

開發(fā) 前端
這篇文章起源于我的 C#內(nèi)功修煉訓(xùn)練營里的一位朋友提的問題:后臺線程的內(nèi)部是如何運(yùn)轉(zhuǎn)的 ? ,猶記得C# Via CLR這本書中 Jeffery 就聊到了他曾經(jīng)給別人解決一個程序無法退出的bug,最后發(fā)現(xiàn)是有一個 Backgrond=false 的線程導(dǎo)致的。

一、背景

1. 講故事

這篇文章起源于我的 C#內(nèi)功修煉訓(xùn)練營里的一位朋友提的問題:后臺線程的內(nèi)部是如何運(yùn)轉(zhuǎn)的 ? ,猶記得C# Via CLR這本書中 Jeffery 就聊到了他曾經(jīng)給別人解決一個程序無法退出的bug,最后發(fā)現(xiàn)是有一個 Backgrond=false 的線程導(dǎo)致的。恰巧在我分析的350+dump中,也還真遇到了。有了這些鋪墊,我覺得有必要簡單的聊一聊。

二、后臺線程的底層邏輯

1. 測試代碼

為了方便講解,先上一段代碼,參考如下:

static void Main(string[] args)
    {
        var thread = new Thread(() =>
        {
            while (true)
            {
                Console.WriteLine(DateTime.Now);
            }
        });

        thread.IsBackground = false;
        thread.Start();
    }

圖片圖片

按照我們樸素的想法,主線程退出,程序自然就terminal,但這個程序并沒有退出?原因就在于設(shè)置了 thread.IsBackground = false; 導(dǎo)致的,當(dāng)然要想程序正常退出改為 ``thread.IsBackground = true;` 即可,接下來我們洞察下 IsBackground 有何魔力導(dǎo)致程序無法退出。

2. 程序?yàn)槭裁礋o法退出

要想知道這個答案,可以用 windbg 附加一下看看主線程此時正在做什么? 參考如下:

0:000> k
 # Child-SP          RetAddr               Call Site
00 0000003f`7d59e498 00007ffd`cd8d0590     ntdll!NtWaitForMultipleObjects+0x14
01 0000003f`7d59e4a0 00007ffd`8f842dd4     KERNELBASE!WaitForMultipleObjectsEx+0xf0
02 (Inline Function) --------`--------     coreclr!Thread::DoAppropriateAptStateWait+0x4a [D:\a\_work\1\s\src\coreclr\vm\threads.cpp @ 3333] 
03 0000003f`7d59e790 00007ffd`8f842c25     coreclr!Thread::DoAppropriateWaitWorker+0x170 [D:\a\_work\1\s\src\coreclr\vm\threads.cpp @ 3467] 
04 0000003f`7d59e850 00007ffd`8f99498e     coreclr!Thread::DoAppropriateWait+0x85 [D:\a\_work\1\s\src\coreclr\vm\threads.cpp @ 3182] 
05 (Inline Function) --------`--------     coreclr!CLREventBase::WaitEx+0x26 [D:\a\_work\1\s\src\coreclr\vm\synch.cpp @ 459] 
06 (Inline Function) --------`--------     coreclr!CLREventBase::Wait+0x26 [D:\a\_work\1\s\src\coreclr\vm\synch.cpp @ 412] 
07 0000003f`7d59e8d0 00007ffd`8f94c185     coreclr!CLREventWaitWithTry+0x9a [D:\a\_work\1\s\src\coreclr\vm\threads.cpp @ 5676] 
08 0000003f`7d59e980 00007ffd`8f8a062b     coreclr!ThreadStore::WaitForOtherThreads+0xabafd [D:\a\_work\1\s\src\coreclr\vm\threads.cpp @ 5715] 
09 0000003f`7d59e9b0 00007ffd`8f83eaad     coreclr!RunMainPost+0x5f [D:\a\_work\1\s\src\coreclr\vm\assembly.cpp @ 1407] 
0a 0000003f`7d59e9f0 00007ffd`8f83e0e7     coreclr!Assembly::ExecuteMainMethod+0x1f5 [D:\a\_work\1\s\src\coreclr\vm\assembly.cpp @ 1524] 
0b 0000003f`7d59ecc0 00007ffd`8f889778     coreclr!CorHost2::ExecuteAssembly+0x267 [D:\a\_work\1\s\src\coreclr\vm\corhost.cpp @ 349] 
...

從卦中數(shù)據(jù)可以看到,主線程正在調(diào)用 ThreadStore::WaitForOtherThreads 方法,貌似是在等待其他線程完成,那具體做了什么呢?這個需要在 coreclr 上尋找答案,刪減后的代碼如下:

void ThreadStore::WaitForOtherThreads()
    {
        if (!OtherThreadsComplete())
        {
            TSLockHolder.Release();

            pCurThread->SetThreadState(Thread::TS_ReportDead);

            DWORD ret = WAIT_OBJECT_0;
            while (CLREventWaitWithTry(&m_TerminationEvent, INFINITE, TRUE, &ret))
            {
            }
        }
    }

    BOOL OtherThreadsComplete()
    {
        return (m_ThreadCount - m_UnstartedThreadCount - m_DeadThreadCount
                - Thread::m_ActiveDetachCount + m_PendingThreadCount
                == m_BackgroundThreadCount);
    }

從卦中看邏輯還是非常簡單的,就是因?yàn)?m_ThreadCount - m_UnstartedThreadCount - m_DeadThreadCount- Thread::m_ActiveDetachCount + m_PendingThreadCount 減完之后和 m_BackgroundThreadCount 對不上,最后在 m_TerminationEvent 事件上等待喚醒。

這里稍微提一下,這幾個值可以通過 !t 顯示出來,參考如下:

圖片圖片

還有一個 Thread::m_ActiveDetachCount 計(jì)數(shù)值,這個值統(tǒng)計(jì)的是那種被coreclr從 ThreadStore 中移除尚未被 delete 的線程對象。結(jié)合 !t 的輸出,很顯然 OtherThreadsComplete() 為 3=2 顯然返回 false。因?yàn)橛?1 個 background 的存在。

3. IsBackground=true 能破局嗎

癥結(jié)我們也找到了,只要m_TerminationEvent事件能夠被喚醒,鏈路就會被再次打通,讓程序安全退出。接下來我們研究下 IsBackground=true 在底層會做什么?簡化后的C++代碼如下:

void Thread::SetBackground(BOOL isBack)
    {
        if (isBack)
        {
            if (!IsBackground())
            {
                SetThreadState(TS_Background);

                if (!IsUnstarted())
                    ThreadStore::s_pThreadStore->m_BackgroundThreadCount++;

                ThreadStore::CheckForEEShutdown();
            }
        }
    }

    void ThreadStore::CheckForEEShutdown()
    {
        if (g_fWeControlLifetime &&
            s_pThreadStore->OtherThreadsComplete())
        {
            BOOL bRet;
            bRet = s_pThreadStore->m_TerminationEvent.Set();
            _ASSERTE(bRet);
        }
    }

哈哈,卦中的化煞方法真的妙不可言,做了如下兩個步驟:

  • 做了 m_BackgroundThreadCount++,這樣 OtherThreadsComplete() 的值就對上了。
  • 使用 m_TerminationEvent.Set 做了事件喚醒,這樣主線程就可以從 WaitForOtherThreads() 方法中逃出生天。

如果有些朋友沒搞明白,我再畫一張簡圖吧:

圖片圖片

4. 判斷線程的前后狀態(tài)

這是最后一個要聊的話題,要想知道線程的前后狀態(tài),這個需要在 coreclr 源碼中尋找答案,參考代碼如下:

void SetThreadState(ThreadState ts)
    {
        InterlockedOr((LONG*)&m_State, ts);
    }

    enum ThreadState
    {
        TS_Background = 0x00000200,    // Thread is a background thread
    }

從代碼中可以看到,只要判斷 ThreadState 中有沒有 0x200 的標(biāo)記即可,接下來用 !t 觀察線程狀態(tài)。

0:000> !t
ThreadCount:      4
UnstartedThread:  0
BackgroundThread: 3
PendingThread:    0
DeadThread:       0
Hosted Runtime:   no
                                                                                                            Lock  
 DBG   ID     OSID ThreadOBJ           State GC Mode     GC Alloc Context                  Domain           Count Apt Exception
   0    1      918 000001FA530317B0  203a220 Preemptive  000001FA574096F8:000001FA5740A5C8 000001fa530273e0 -00001 MTA 
   6    2     37c8 000001FA53009B70    21220 Preemptive  0000000000000000:0000000000000000 000001fa530273e0 -00001 Ukn (Finalizer) 
   7    3     2c7c 000001FA5307F700    2b220 Preemptive  0000000000000000:0000000000000000 000001fa530273e0 -00001 MTA 
   8    4     3bd4 0000023AE951DFD0    2b020 Preemptive  000001FA57563A08:000001FA57565010 000001fa530273e0 -00001 MTA

從卦中可以輕松的看到 DBG=8 的線程狀態(tài)是 2b020,自然就是前臺線程咯。

三、總結(jié)

現(xiàn)在我們知道了前后臺線程本質(zhì)上是 coreclr 弄出來的概念,并非系統(tǒng)線程素有之物。還是那句話,知識不重要,重要的是會使用合適的工具和保有的探索心,這也是在訓(xùn)練營里重度強(qiáng)調(diào)的。

責(zé)任編輯:武曉燕 來源: 一線碼農(nóng)聊技術(shù)
相關(guān)推薦

2021-03-29 00:02:10

C#Attribute元素

2024-01-02 13:26:39

TLSC#線程

2022-11-02 08:51:01

2023-12-07 07:26:04

2024-08-26 14:46:57

2020-10-30 07:11:31

C 語言編程

2024-06-28 12:47:29

C#弱引用底層

2022-08-30 07:39:57

C++namespace隔離

2020-10-23 07:00:00

C++函數(shù)

2020-12-29 05:33:40

TomcatSpringBoot代碼

2018-05-16 08:58:04

用戶畫像存儲

2025-01-10 08:15:22

C#異步底層

2018-11-30 12:48:36

SDS故障硬件

2023-03-05 18:40:39

iptables防火墻軟件

2020-12-09 16:55:57

程序員技術(shù)

2021-05-12 18:02:23

方法創(chuàng)建線程

2021-01-28 22:31:33

分組密碼算法

2023-09-22 17:36:37

2020-05-22 08:16:07

PONGPONXG-PON

2018-06-07 13:17:12

契約測試單元測試API測試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

三级视频在线| 国产午夜精品一区二区三区四区| 日韩国产精品大片| 亚洲天堂久久久久久久| 亚洲欧美一区二区三区四区| 国产h视频在线播放| 欧美成人片在线观看| 亚洲精品8mav| av资源一区二区| 亚洲一区二区久久久久久久| 午夜国产福利视频| 亚洲精品乱码久久久久久久| 日本视频在线观看免费| free性m.freesex欧美| 欧美3p在线观看| av资源网一区| 欧美亚洲国产怡红院影院| 日韩中文字幕网| 国产 高清 精品 在线 a| 欧美成人蜜桃| 伦理片一区二区| 国产在线一二| 精品一区二区日韩| 91精品国产福利在线观看| 一区二区三区四区五区视频| 鲁丝片一区二区三区| 国产一区二区免费电影| 亚洲国产精品久久久久久女王| 亚洲精品无码久久久久| 91p九色成人| 中文字幕在线不卡| 久久免费国产视频| 久久久久久久久久久免费视频| 国产无套丰满白嫩对白| 亚洲精品3区| 国产精品无遮挡| 国产精品一二三在线| 成人在线观看a| 亚洲精品一区二区三区在线播放| 久久精品视频观看| 夜夜嗨网站十八久久| 综合色中文字幕| 久久国产精品电影| 日本久久精品一区二区| 日韩三级视频在线| 五月婷婷综合在线观看| 国产理论视频在线观看| 最新国产拍偷乱拍精品| 一色桃子一区二区| 欧美一区2区视频在线观看| 欧美精品一区二区三区在线四季| 91国产免费视频| 台湾佬中文娱乐网欧美电影| 99精品国产高清一区二区麻豆| 成人性生交大片免费网站 | 成人精品国产| 精品久久在线播放| 中文字幕久久综合| 97超碰人人模人人人爽人人爱| 影音先锋亚洲精品| 欧美情侣性视频| 日韩精品中文字幕有码专区| 奇米视频888战线精品播放| 亚洲午夜精品一区| 你懂的视频在线| 国产精品系列在线观看| 国产精品久久久久99| 91中文字幕永久在线| 黄色欧美在线| 精品视频在线免费观看| 免费看的黄色大片| 头脑特工队2在线播放| 成人国产电影网| 国产精品亚洲视频在线观看| 亚洲AV无码国产精品| 久久久久毛片免费观看| 国产精品色在线观看| av观看久久| 国产一区二区三区视频免费观看| 蜜乳av一区二区三区| 久国内精品在线| 92国产精品久久久久首页| 37pao成人国产永久免费视频| 啪啪免费视频一区| 日韩亚洲精品在线观看| av电影一区二区| 久久激情视频免费观看| 无码h肉动漫在线观看| 美女精品久久| 日本韩国一区二区| 国产无限制自拍| 黄色动漫在线观看| 国产午夜精品理论片a级大结局| 裸模一区二区三区免费| 人妻中文字幕一区| 久久午夜免费电影| 欧美精品亚洲| 美女写真理伦片在线看| 亚洲一区在线看| 国产精品一区二区免费看| 亚洲免费一级片| 99精品欧美一区二区三区综合在线| 丁香网亚洲国际| 欧美大尺度激情区在线播放| www.狠狠爱| 欧美xxav| 欧美大成色www永久网站婷| 日本少妇在线观看| 亚洲精品婷婷| 在线性视频日韩欧美| 鲁一鲁一鲁一鲁一色| 高h视频在线观看| 午夜久久久久久久久| 老司机午夜av| 韩国美女久久| 欧美性受极品xxxx喷水| 午夜免费福利视频在线观看| 日韩中文字幕视频网| 精品国产免费久久| 日韩五码在线观看| 91高清免费视频| 国产成人avxxxxx在线看| 色91精品久久久久久久久| 精品美女一区| 亚洲国产成人爱av在线播放| 亚洲欧美日韩区| 天堂www中文在线资源| 99精品人妻无码专区在线视频区| 久久99蜜桃精品| 91精品视频在线看| 人妻91麻豆一区二区三区| 国产亚洲欧美一区在线观看| 国产午夜精品一区| 天天操天天射天天| 久久精品av| 亚洲欧美日韩一区二区三区在线观看| 亚洲欧美电影在线观看| 五月天激情在线| 亚洲国产cao| 看欧美ab黄色大片视频免费| 国内精品不卡| 在线观看日韩毛片| 国产ts在线观看| 成人在线视频免费观看| 欧美黄色三级网站| 国产一区二区视频免费| 日日骚欧美日韩| 国产精品xxxx| 幼a在线观看| 欧美性高跟鞋xxxxhd| 亚洲爱爱爱爱爱| 国产精品无码自拍| 成人另类视频| 亚洲视频免费一区| 免费看日b视频| 久久亚洲精品人成综合网| 精品精品欲导航| 亚洲一区二区三区四区精品| 国产传媒在线| 在线视频国内一区二区| 91日韩精品视频| 波多野结衣中文字幕久久| gogogo免费视频观看亚洲一| 5566av亚洲| 成人免费网址| 欧美一区二区三区日韩视频| 日本一二三区在线| 欧美日韩夜夜| 日韩在线中文视频| 一区二区三区黄| 中文字幕一区在线| 欧美成人在线直播| 国产精品嫩草69影院| 精品视频91| 久久久精品2019中文字幕神马| 久久久久噜噜噜亚洲熟女综合| 99精品热6080yy久久| 成人免费视频a| 黄色av网站在线看| 欧美丝袜丝交足nylons图片| 香蕉在线观看视频| 欧美激情 亚洲a∨综合| 欧美黄色www| 天堂中文在线资源| 色天使久久综合网天天| 蜜臀久久99精品久久久久久| 日本欧美一区二区| 九九99玖玖| 1区2区在线| 日韩精品视频免费专区在线播放 | 麻豆久久久av免费| 日韩视频网站在线观看| 婷婷综合激情| 亚洲成av人片一区二区| 2025韩国理伦片在线观看| 成人看片网页| 亚洲国产精品福利| 九一在线免费观看| 久久av中文字幕片| 日韩av在线电影观看| 国产美女高潮在线观看| 日韩黄色在线免费观看| 日产欧产va高清| 99精品在线免费| 日本三级免费网站| 一区二区美女| 国产情人节一区| 最新日本在线观看| 亚洲欧美日韩图片| 99在线小视频| 一本大道久久a久久精品综合| 无码国产精品久久一区免费| 欧美日韩精品一本二本三本| 国产精品乱码视频| 日韩国产网站| 精品一区二区免费看| 豆国产97在线| 巨茎人妖videos另类| 中国china体内裑精亚洲片| 伊人成年综合网| 国产欧美一区二区精品性色| 欧美专区第二页| 中文字幕av亚洲精品一部二部| 国产精品久久一区主播| 男女在线视频| 精品香蕉一区二区三区| 免费观看日批视频| 一片黄亚洲嫩模| 韩国女同性做爰三级| 亚洲一级网站| 中文字幕一区综合| 亚洲图区在线| 亚洲午夜av电影| 国产成人麻豆免费观看| 亚洲精品日韩专区silk| 国产福利在线导航| 99久久国产综合精品麻豆| 中文字幕线观看| 国产精品入口66mio| 欧美一区二区性放荡片| 亚洲观看黄色网| 九色综合国产一区二区三区| 日韩国产精品一区二区| 日韩欧美久久| 欧美精品少妇videofree| 欧美日韩影视| 日韩免费一区二区三区在线播放| 亚洲另类欧美日韩| www国产成人| 日韩高清在线播放| 欧美大奶一区二区| 国产精品国产三级欧美二区| 国产精品免费精品自在线观看| 欧美在线性视频| 国产精品一区二区三区在线免费观看| 亚洲自拍偷拍网站| 美女被到爽高潮视频| 26uuu另类欧美亚洲曰本| 特种兵之深入敌后| 九一九一国产精品| 不用播放器的免费av| 久久草av在线| www,av在线| 天堂а√在线官网| 欧美丝袜自拍制服另类| 国产成人无码av| 欧美日韩一区二区在线播放| 免费看黄色aaaaaa 片| 国产成人精品亚洲777人妖| 极品粉嫩美女露脸啪啪| 麻豆国产一区二区| 久久人人爽人人爽人人av| √天堂8在线网| 麻豆一区二区在线观看| 欧美成人hd| 日韩久久午夜影院| 国产又粗又长又大视频| 精品国产91久久久久久老师| 九九热精品视频在线| 亚洲免费在线观看视频| 亚洲欧美日韩第一页| 最近中文字幕一区二区三区| 久久国产波多野结衣| 亚洲欧美日韩国产综合| 成人免费性视频| 91极品在线| 日韩在线播放一区| 蜜桃视频网站在线| 欧美极品少妇xxxxⅹ喷水| 亚洲欧美成人影院| yellow中文字幕久久| caopen在线视频| 97精品国产97久久久久久免费| 自拍视频在线看| 欧美影院在线播放| 国产夫妻在线播放| 国产精品人成电影在线观看| 美国十次综合久久| 久久综合毛片| 久久电影院7| 美乳视频一区二区| 欧美aaaa视频| 中国丰满熟妇xxxx性| 最新日韩av| 一道本在线免费视频| 成人在线免费观看网站| 欧美日韩三级一区二区| 在线日韩国产网站| 亚洲激情男女视频| 性欧美精品一区二区三区在线播放| 日韩理论电影中文字幕| 成人免费黄色网| 任你躁在线精品免费| 欧美第一淫aaasss性| 欧美性爽视频| 国产精品久久久久7777婷婷| 91成人噜噜噜在线播放| 日韩av一级大片| 欧美影视一区| 国产黄色片免费在线观看| 亚洲中字黄色| 交换做爰国语对白| 成人午夜视频网站| 蜜桃av免费在线观看| 亚洲视频中文字幕| 国产一级一片免费播放放a| 日本乱人伦aⅴ精品| 伊人成人在线观看| 亚洲国产综合色| 国产精品视频一区在线观看| 亚洲视频一区二区在线| 在线天堂中文字幕| 精品国产一区二区三区av性色| 在线观看亚洲一区二区| 欧美区在线观看| 一本色道久久综合熟妇| 日韩免费一区二区三区| 香蕉久久久久久| 亚洲欧美日韩另类| 精品夜夜澡人妻无码av| 日本欧美一区二区在线观看| 99精品999| 免费在线观看精品| 亚洲77777| 99精品黄色片免费大全| 老司机福利在线观看| 亚洲成人综合网站| 99久久久无码国产精品免费| 亚洲一级黄色av| 成人超碰在线| 国产精品爽爽爽爽爽爽在线观看| 久久国产精品色av免费看| 欧美a级免费视频| 蜜乳av一区二区| 国产91在线播放九色| 在线观看不卡一区| 国产又粗又长又黄| 久久亚洲精品中文字幕冲田杏梨 | 91精品欧美一区二区三区综合在| 99久久一区二区| 色小说视频一区| 欧美第一视频| 国产精品免费一区二区三区在线观看 | 欧美成人中文字幕| 成人在线观看免费播放| 国产精品露脸av在线| 色999韩欧美国产综合俺来也| 日韩av电影在线免费播放| www.成人| 成人免费高清完整版在线观看| 国产精品99视频| www.超碰com| 99精品黄色片免费大全| 久久久成人免费视频| 亚洲国产精品嫩草影院久久| 1stkiss在线漫画| 国产成人97精品免费看片| 五月国产精品| 一本一道久久a久久综合精品 | 91国产精品| 桥本有菜av在线| 成人久久久精品乱码一区二区三区| 国产在线欧美在线| 一区二区三区丝袜| 欧美日韩国产精品一区二区三区| 亚洲国产精品小视频| 国产99在线观看| 韩国成人一区| 国产偷自视频区视频一区二区| 丁香花五月婷婷| 91精品麻豆日日躁夜夜躁| 一区二区三区视频在线观看视频| 亚洲一区二区少妇| 亚洲在线视频播放| 日韩欧美国产系列| 黄视频在线免费看| 国产精品久久久久久久小唯西川| 国产毛片一区| 美女搡bbb又爽又猛又黄www| 午夜精品福利久久久|