亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#多線程開發(fā)實戰(zhàn)記錄之線程基礎

 更新時間:2021年09月03日 11:40:55   作者:阿輝  
線程是一個獨立的運行單元,每個進程內部有多個線程,每個線程可以各自同時執(zhí)行指令,每個線程有自己獨立的棧,但是與進程內的其他線程共享內存,這篇文章主要給大家介紹了關于C#多線程開發(fā)實戰(zhàn)記錄之線程基礎的相關資料,需要的朋友可以參考下

前言

最近由于工作的需要,一直在使用C#的多線程進行開發(fā),其中也遇到了很多問題,但也都解決了。后來發(fā)覺自己對于線程的知識和運用不是很熟悉,所以將利用幾篇文章來系統(tǒng)性的學習匯總下C#中的多線程開發(fā)。

線程基礎

進程是操作系統(tǒng)分配資源的最小單元,線程是操作系統(tǒng)調度的最小單元” 這句話應該學習計算機的朋友或多或少都聽說過,這在操作系統(tǒng)這門課中是很重要的一個概念。

在操作系統(tǒng)中可以同時運行很多個應用程序,那么你知道計算機是如何分配和調度這些應用程序去使用CPU進行工作的嗎?

這里面就牽扯到了進程、線程的概念,也就是我們接下來要學習的內容。

一個應用程序會有很多個線程,但是只能有一個進程。也就是說一個進程中可以有很多個線程。那么這是為什么呢?以前計算機只有一個計算模塊,每次只能單一的執(zhí)行一個計算單元,不能同時執(zhí)行多個計算任務?,F(xiàn)在隨著科技的發(fā)展,有了多核CPU,可以一次性執(zhí)行多個應用程序,這樣就實現(xiàn)了多任務。操作系統(tǒng)為了不讓一個應用程序獨占CPU,導致其余程序掛起等待,不得不設計出一種將物理計算單元分割為一些虛擬的進程,并給予每個執(zhí)行程序一定量的計算能力。此外,操作系統(tǒng)必須始終能夠優(yōu)先訪問CPU,并能調整不同程序訪問CPU的優(yōu)先級(說白了就是典型的以空間換時間)。

線程正是這一概念的實現(xiàn),可以認為線程是一個虛擬的進程,用于獨立運行一個特定的程序。

大量使用線程會消耗大量的OS資源

那么為什么需要使用線程呢!其實就是為了在相同的時間內,讓操作系統(tǒng)或CPU干更多的活,那么在C#中線程應該如何使用或者說在什么場景下使用呢!

在C#中關于線程的使用,大多數(shù)時候是在當程序需要處理大量繁瑣、占用資源多、花費大量時間的任務時進行應用,比如訪問數(shù)據(jù)庫,視頻顯示,文件IO操作、網(wǎng)絡傳輸?shù)取?/p>

線程在應用程序中可以進行如何操作:1、創(chuàng)建線程;2、暫停線程;3、線程等待;4、終止線程。

1、創(chuàng)建線程

通過聲明并實例化Thread就可以創(chuàng)建線程,它接收方法作為參數(shù)。使用Thread.Start()就可以開啟子線程,讓其去執(zhí)行方法中的內容。

        static void Main(string[] args)
        {            
            //新創(chuàng)建的線程中輸出
            Thread oneThread = new Thread(PrintNumber);
            oneThread.Start();

            //主線程中輸出
            PrintNumber();
            Console.ReadKey();
        }

        static void PrintNumber() 
        {
            Console.WriteLine("開始......");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
            }
        }

可以看到當我們在子線程和主線程中同時輸出PrintNumber()中的內容時,它是亂的隨機交叉輸出的。

2、暫停線程

暫停線程故名思意就是讓線程暫停,不讓其占用CPU資源,在一直等待,啥時候取消暫停就恢復運行。在C#中暫停就是讓這個線程進入睡眠狀態(tài),讓其休眠,不讓其占用系統(tǒng)資源就可以了。

  Thread.Sleep(TimeSpan.FromSeconds(2));    //睡眠2s

3、線程等待

線程等待就是多個線程在處理某個任務時,某個線程必須等待前一個線程處理所有數(shù)據(jù)后才可以進行執(zhí)行,在這個期間,這個線程是阻塞狀態(tài)的。只有前一個線程完事了,他才可以再繼續(xù)執(zhí)行。

        static void Main(string[] args)
        {            
            //新創(chuàng)建的線程中輸出
            Thread oneThread = new Thread(PrintNumber);
            oneThread.Start();
            oneThread.Join();

            //主線程中輸出
            PrintNumber();
            Console.ReadKey();
        }

也就是說上面的程序主線程必須得等oneThread線程執(zhí)行完PrintNumber方法后,它才可以執(zhí)行。

4、線程終止

就是線程在執(zhí)行過程中,利用某些操作(Thread.Abort())可以使其線程立即退出,不進行工作了。

        static void Main(string[] args)
        {            
            //新創(chuàng)建的線程中輸出
            Thread oneThread = new Thread(PrintNumber);
            oneThread.Start();

            Thread.Sleep(TimeSpan.FromSeconds(6));
            oneThread.Abort();

            //主線程中輸出
            PrintNumber();
            Console.ReadKey();
        }

上面的程序可以看到,當主程序再等待6s后,立即將oneThread線程終止掉。

其實Abort()方法是給線程注入了ThreadAbortException方法,導致線程被終結,這其實很危險,因為該線程可能正在處理某些重要的數(shù)據(jù),比如接收傳輸數(shù)據(jù)等,這樣子就傳遞摧毀了程序,數(shù)據(jù)也就丟失了。還有就是這個方法不能保證100%終止線程。有時候有些異常會被吃掉,我們可以利用某些關鍵變量在子線程中進行控制,從而取消線程的執(zhí)行就可以。

在實際編碼使用線程的過程中,可以通過oneThread.ThreadState來獲取目前線程的狀態(tài)。有時候我們也可以手動的設置線程的優(yōu)先級,設置為最高的則提前執(zhí)行,但是這個只是針對于單核CPU時,目前市面上基本都是多核的了,這種使用場景也就很少了。

一般我們創(chuàng)建的線程都是屬于前臺線程,通過手動設置ontThread對象的IsBackground屬性為true時才會為后臺線程。通常前臺線程會比后臺線程提前執(zhí)行完。當前臺線程執(zhí)行完成后,程序結束并且后臺線程被終結。進程會等待所有的前臺線程完成后再結束工作,但是如果只剩下后臺線程,進程會直接結束工作。

C#中的lock關鍵字

某一個資源當被多個線程同時訪問時,可能這個資源的某些值對于各個線程來說會出問題。如果在某一時刻,一個線程是使其遞增,一個線程是遞減,會導致其值不唯一,各個線程拿到的值不對。這種情況就是所謂的競爭條件,競爭條件是多線程環(huán)境中非常常見的導致錯誤的原因。

    class PepoleCount 
    {
        int count = 0;
        public void AddCount() 
        {
            ++count;            
        }
        public void DeleteCount() 
        {
            --count;
        }    
    }

比如是上面的程序,當兩個線程同時訪問這個PepoleCount類時,會導致count變量出現(xiàn)競爭條件。就是每個線程可能拿到的數(shù)值不是最新的。那么如何辦呢,此時就需要使用到lock機制,也就是加鎖。目的是為了當一個線程訪問某個資源時,其余線程如果在訪問時,必須等待當前訪問完事后,它才可以訪問。保證了數(shù)據(jù)的有效性。

lock關鍵字是如果鎖定了一個對象,需要訪問該對象的所有其他線程則會處于阻塞狀態(tài),并等待知道該對象解除鎖定才可以訪問。

    class PepoleCount 
    {
        private readonly object _syncRoot = new object();
        int count = 0;
        public void AddCount() 
        {
            lock(_syncRoot)
            {
                ++count;            
            }            
        }
        public void DeleteCount() 
        {
            lock(_syncRoot)
            {
            --count;
            }
        }    
    }

關于加鎖這塊還是有很多講究的,不是說每一個方法,每一個變量都需要進行加鎖,如果頻繁的加鎖會導致其余線程處于阻塞狀態(tài),那么也會導致應用程序出現(xiàn)嚴重的性能問題。

總結

到此這篇關于C#多線程開發(fā)實戰(zhàn)記錄之線程基礎的文章就介紹到這了,更多相關C#多線程基礎內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C#判斷訪問來源是否為搜索引擎鏈接的方法

    C#判斷訪問來源是否為搜索引擎鏈接的方法

    這篇文章主要介紹了C#判斷訪問來源是否為搜索引擎鏈接的方法,實例分析了C#解析URL來源的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • C#中實現(xiàn)多繼承的方法

    C#中實現(xiàn)多繼承的方法

    這篇文章主要介紹了C#中實現(xiàn)多繼承的方法,本文通過給接口添加擴展的方法實現(xiàn)了C#的多繼承,需要的朋友可以參考下
    2014-08-08
  • C#中DataTable排序、檢索、合并等操作實例

    C#中DataTable排序、檢索、合并等操作實例

    這篇文章主要介紹了C#中DataTable排序、檢索、合并等操作實例,其中詳細介紹了DataTable.Select的一些注意問題和使用技巧等,需要的朋友可以參考下
    2014-04-04
  • Unity實現(xiàn)鼠標或者手指點擊模型播放動畫

    Unity實現(xiàn)鼠標或者手指點擊模型播放動畫

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)鼠標或者手指點擊模型播放動畫,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01
  • C#中析構函數(shù)、Dispose、Close方法的區(qū)別

    C#中析構函數(shù)、Dispose、Close方法的區(qū)別

    本文詳細對比了C#中析構函數(shù)、Dispose和Close方法的區(qū)別,三者都是釋放資源,本文介紹了他們各自的使用方法和使用場景,希望對大家有所幫助。
    2016-04-04
  • C#序列化成XML注意細節(jié)

    C#序列化成XML注意細節(jié)

    最常用的序列化是把某個類序列化成二進制文件.但有時我們也會把類序列化成xml文件,需要的朋友可以參考下
    2012-11-11
  • C#中緩存的基本用法總結

    C#中緩存的基本用法總結

    這篇文章主要介紹了C#中緩存的基本用法,對C#初學者來說是很有必要熟練掌握的內容,需要的朋友可以參考下
    2014-08-08
  • c# 可疑文件掃描代碼(找到木馬)(簡)

    c# 可疑文件掃描代碼(找到木馬)(簡)

    c# 可疑文件掃描代碼(找到木馬),需要的朋友可以參考下。
    2010-05-05
  • 使用Log4net進行日志記錄

    使用Log4net進行日志記錄

    本文詳細講解了使用Log4net進行日志記錄的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • C#如何獲取當前路徑的父路徑

    C#如何獲取當前路徑的父路徑

    這篇文章主要介紹了C#如何獲取當前路徑的父路徑問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07

最新評論