精品欧美一区二区三区在线观看 _久久久久国色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ù)棧公眾號

国产精品午夜一区二区三区| 极品粉嫩国产18尤物| 在线看的黄色网址| 亚洲av色香蕉一区二区三区| 精品国产中文字幕第一页| 亚洲午夜久久久久久久久电影网 | 国产欧美自拍一区| 国产人妖乱国产精品人妖| 欧美激情精品久久久久久黑人| 亚洲免费av一区二区三区| 香蕉视频911| 黄色亚洲免费| 欧美一级二级在线观看| 亚洲一区二区三区加勒比| 日本a级c片免费看三区| 天堂俺去俺来也www久久婷婷| 亚洲免费观看高清完整版在线| 国产精品一区=区| 中文字幕网站在线观看| av在线理伦电影| 午夜激情久久| 黄色成人在线免费| 国产一区二区在线网站| 国产亚洲精品女人久久久久久| 日韩中文在线| 亚洲一区二区精品3399| 性欧美.com| 伊人网视频在线| 97精品国产| 在线91免费看| 国产a级黄色大片| 黑人操亚洲女人| 一区二区国产在线观看| 日韩久久午夜影院| 91av俱乐部| 在线观看美女网站大全免费| 老司机精品视频在线| 日韩在线视频网| 在线视频日韩欧美| 毛片网站在线看| 波多野结衣办公室33分钟| 亚洲国产精品无码久久| 麻豆久久一区二区| 欧美在线视频导航| 夫妇交换中文字幕| 日韩成人在线电影| 亚洲乱码一区二区三区在线观看| 日韩少妇中文字幕| 国产女同91疯狂高潮互磨| 欧美精品三级| 日韩av中文字幕在线免费观看| 天天摸天天碰天天添| 五月婷婷在线视频| 国产综合久久久久久久久久久久 | 一色道久久88加勒比一| 免费福利视频一区| 在线看国产一区二区| 亚洲自拍偷拍一区二区三区| 亚洲AV无码精品色毛片浪潮| 国产乱人伦偷精品视频免下载| 国内免费久久久久久久久久久| av中文字幕免费观看| 99久久综合国产精品二区| 日韩毛片视频在线看| 国产在线精品一区二区三区》| 亚洲h视频在线观看| 国产成人综合在线播放| 日本乱人伦a精品| 欧洲猛交xxxx乱大交3| 久久男人av| 欧美日韩国产免费一区二区| 一卡二卡三卡视频| 中文字幕在线视频区| 国产精品精品国产色婷婷| 国产欧美一区二区三区另类精品 | 成人黄色av网站在线| 国产www精品| 欧美精品一区二区蜜桃| 国产乱码精品一区二区三区四区| 亚洲午夜精品久久久久久久久久久久| 免费不卡av网站| 少妇一区视频| 亚洲成人福利片| 中文字幕久精品免| 黄色影院在线播放| 不卡一区在线观看| 欧美日韩精品免费观看| 亚洲欧美另类一区| 91尤物视频在线观看| 亚洲综合小说区| 最新中文字幕在线观看视频| 99riav1国产精品视频| 琪琪第一精品导航| 国产精品久久久久久久免费 | 亚洲人成亚洲精品| 欧美一级片在线看| 亚洲欧美日韩一级| 日韩欧洲国产| 亚洲天堂av电影| aa片在线观看视频在线播放| 试看120秒一区二区三区| 亚洲国语精品自产拍在线观看| 男插女视频网站| 欧美性生活一级片| 久久精品国产一区二区三区| 性猛交娇小69hd| 久操国产精品| 亚洲欧美日韩精品久久奇米色影视| 欧美xxxxx少妇| 91精品尤物| 日韩女优毛片在线| 无套白嫩进入乌克兰美女| 日本午夜精品久久久| 久久久av免费| 无码人妻久久一区二区三区 | 91精品综合久久久久久久久久久| 久久久人成影片一区二区三区观看| 姑娘第5集在线观看免费好剧| 成人精品视频网站| 一区二区在线不卡| 国模冰冰炮一区二区| 亚洲1区2区3区视频| 精品成在人线av无码免费看| 成人av色网站| 亚洲毛片在线看| 久久精品亚洲无码| 国内精品久久久久久久影视蜜臀 | 亚洲综合999| 97中文字幕在线| 丁香影院在线| 精品国产电影一区| 中文字幕在线观看视频www| 外国成人毛片| 亚洲无限av看| 日日骚av一区二区| jvid福利写真一区二区三区| 久久久久成人精品免费播放动漫| 日本福利午夜视频在线| 久久久久久一级片| 永久久久久久| 日本综合视频| 日韩欧美国产一区二区三区| 免费观看特级毛片| 亚洲综合中文| 97碰碰碰免费色视频| 久久久久久久久久成人| 99视频超级精品| 久久99中文字幕| aaa国产精品视频| 日韩电影大全免费观看2023年上| 国产亚洲精久久久久久无码77777| 国产美女娇喘av呻吟久久| 一区二区三区电影| 欧美videos粗暴| 亚洲精品在线观| 精品无码在线观看| 日本成人在线一区| 999国内精品视频在线| 少妇性bbb搡bbb爽爽爽欧美| 午夜伊人狠狠久久| 久久久老熟女一区二区三区91| 欧美日韩色图| 91精品久久久久久久久久| 天天摸夜夜添狠狠添婷婷| 日本一区二区三区免费乱视频| 久久综合久久色| 一区二区三区四区高清视频 | 久久蜜桃av一区精品变态类天堂| 中国人体摄影一区二区三区| av成人在线网站| 亚洲激情电影中文字幕| 亚洲影院在线播放| 国产亲近乱来精品视频| 亚洲一级片网站| 日韩av影院| 国产成人精品国内自产拍免费看| av资源网在线观看| 精品国产户外野外| 国产手机在线观看| 精品一区二区免费| 国产一区精品在线| 依依综合在线| 北条麻妃一区二区三区中文字幕| 亚洲第一在线播放| 福利电影一区二区| 最新av在线免费观看| 51社区在线成人免费视频| 欧美中文字幕在线| 免费的黄网站在线观看| 欧美综合天天夜夜久久| 天天爽天天爽天天爽| 日韩高清在线电影| 牛人盗摄一区二区三区视频| 蜜桃麻豆av在线| 亚洲成人三级在线| 免费中文字幕在线观看| 久久九九全国免费| 亚洲区 欧美区| 亚洲成人原创| 国产一区二区三区免费不卡| 一区二区视频免费完整版观看| 欧美精品性视频| a级片免费视频| 亚洲天堂免费看| 91 视频免费观看| 亚洲网色网站| 欧美日韩成人一区二区三区| 一区二区三区四区高清视频 | 欧美丝袜足交| 91在线观看免费高清| 久操视频在线观看| 这里只有精品99re| 国产一级一级国产| 夜夜精品浪潮av一区二区三区| 变态另类ts人妖一区二区| 成人av在线一区二区三区| 激情黄色小视频| 婷婷久久一区| 青青影院一区二区三区四区| 午夜精品久久久久久久久久蜜桃| 国产亚洲一区二区在线| 亚洲狼人综合网| 欧美一区二区日韩一区二区| 亚洲大尺度在线观看| 国产欧美精品日韩区二区麻豆天美| 欧美一级片在线免费观看| 激情综合中文娱乐网| 国产精品久久成人免费观看| 6080成人| 亚洲精品免费网站| 久久久久黄色| 国产精品99久久久久久白浆小说| 麻豆理论在线观看| 久久久久免费视频| 欧美性猛交 xxxx| 欧美性猛交99久久久久99按摩| 亚洲国产日韩一区无码精品久久久| 成人免费毛片a| 97xxxxx| 红桃视频亚洲| 97干在线视频| 国产精品vip| 久久久久久久久久久综合| 雨宫琴音一区二区三区| 丰满女人性猛交| 欧美aaaa视频| 一区二区三区四区欧美| 国产电影一区二区在线观看| 一本色道久久综合亚洲精品婷婷| 成人同人动漫免费观看 | 一级淫片免费看| 一区二区三区免费| 欧美xxxx黑人xyx性爽| 悠悠色在线精品| 香蕉视频久久久| 国产女主播视频一区二区| 人人妻人人澡人人爽| 中文子幕无线码一区tr| 亚洲精品久久一区二区三区777 | 国产精品嫩草影院8vv8| 精品亚洲免费视频| 精品国产一二区| 99国内精品久久| www在线观看免费视频| 日本一区二区三区高清不卡| 99热99这里只有精品| 亚洲人妖av一区二区| 久久久久久久久久久97| 午夜视频一区在线观看| 国产中文字幕视频| 欧美日韩在线观看一区二区 | 成人欧美视频在线| 免费观看成人性生生活片| 国产精品久久久久久久久男| segui88久久综合9999| 久久精视频免费在线久久完整在线看| a免费在线观看| 综合国产在线观看| 亚洲色图21p| 在线视频欧美日韩精品| 国产一区久久精品| 久久久视频精品| 黄色精品视频| 成人av播放| 日本在线成人| 免费成人看片网址| 图片小说视频色综合| 欧美视频在线免费播放| 午夜视频一区| 男插女免费视频| 亚洲尤物精选| 毛片在线视频播放| 奇米888四色在线精品| 日本黄色www| 久久久99精品免费观看不卡| 高h视频免费观看| 91久久香蕉国产日韩欧美9色| 黑人一级大毛片| 精品美女久久久久久免费| 午夜三级在线观看| 五月综合激情婷婷六月色窝| 亚洲天堂网视频| 欧美日韩综合在线免费观看| 亚洲老妇色熟女老太| 中文国产成人精品久久一| 91超碰在线| 成人综合网网址| 国产一区二区在线| 奇米影视亚洲色图| 国产一区视频在线看| 久久精品—区二区三区舞蹈 | 成品人视频ww入口| 免费一级片91| 欧美成年人视频在线观看| 成人一区在线观看| 久久人妻无码aⅴ毛片a片app| 欧美性色xo影院| 韩国av免费在线| 精品久久久av| av在线一区不卡| 久久资源亚洲| 精品二区久久| 久久无码人妻一区二区三区| 国产精品国产三级国产三级人妇 | 日韩高清成人| 久久精品ww人人做人人爽| 欧美另类专区| 99九九99九九九99九他书对| 欧美激情资源网| www.久久久久久久| 亚洲人成电影网站色xx| 特黄毛片在线观看| 国产精品69久久| 奇米777国产一区国产二区| 996这里只有精品| 国产另类ts人妖一区二区| 国产日产在线观看| 精品视频在线看| av网站在线免费播放| 国产精品69久久| 欧美老女人另类| 国产真人无码作爱视频免费| 久久久久9999亚洲精品| 天天干在线播放| 亚洲男人天天操| 香蕉久久免费电影| 亚洲乱码一区二区三区三上悠亚| 亚洲高清资源在线观看| 亚洲图色中文字幕| 国产精品乱人伦| 久久精品国产亚洲av麻豆色欲 | 国产精品视频不卡| 精品国精品国产自在久国产应用 | 色婷婷综合久久久久中文字幕1| 视频精品导航| 香蕉视频在线网址| 国产成人综合视频| 日韩伦人妻无码| 欧美日韩一卡二卡三卡| www在线免费观看| 国产日韩欧美成人| 自产国语精品视频| 日本天堂在线播放| 精品福利樱桃av导航| 久久天堂电影| 欧美激情视频播放| 国内精品免费| 37pao成人国产永久免费视频| 国产日韩欧美精品一区| 日韩免费一二三区| 日韩电影大片中文字幕| 亚洲国产尤物| 久久观看最新视频| 日本亚洲三级在线| 多男操一女视频| 精品国产乱码久久久久久免费| 国产h片在线观看| 日本精品一区二区三区视频| 另类小说视频一区二区| 久久国产精品波多野结衣| 日韩av一区二区在线| 国产成人精品一区二区三区在线| 成人在线免费高清视频| av亚洲精华国产精华精华| www.av88| 久久免费福利视频| 国产一区二区观看| 亚洲 自拍 另类 欧美 丝袜| 一本到一区二区三区| 欧美一区二区三区成人片在线| 日本精品va在线观看| 亚洲精品网址| 欧美多人猛交狂配| 日韩一二三区视频| 欧美特黄aaaaaaaa大片| 国产精品啪啪啪视频| 久久精品夜夜夜夜久久| 亚洲精品一级片| 国产精品视频免费在线| aa国产精品|