1.進程和線程是啥?
進程:進程就是一個應(yīng)用程序,對電腦的各種資源的占用
線程:線程是程序執(zhí)行的最小單位,任何操作都是線程完成的,線程依托進程存在的,一個進程可以有多個線程
2.多線程
為啥會出現(xiàn)多此線程?
計算機的角度,因為CPU太快了,其他硬件跟不上CPU的速度。CPU可以分為時間片,大概就是時間分片---上下文切換(加載環(huán)境--計算--保存環(huán)境)。
從微觀角度上說,一個核一個時刻,只能執(zhí)行一個線程;宏觀上來說是多線程并發(fā)。
另外CPU多核,可以獨立工作。例如計算機是4核8線程中,核指的就是物理的核,線程指的是物理的核。
3.C#語言的線程
就是指Thread(.net 1.0的時候就出現(xiàn)了),Thread是一個類,是C#語言多線程對象的封裝。
多線程缺點
線程也是程序,所以線程運行需要占用計算機資源,線程越多占用資源也越多。(占內(nèi)存多)
多線程需要協(xié)調(diào)和管理,所以需要CPU跟蹤線程,消耗CPU資源。(占cpu多)
線程之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題。多線程存在資源共享問題)
線程太多會導致控制太復(fù)雜,最終可能造成很多Bug。(管理麻煩,容易產(chǎn)生bug)
線程安全
如果多個線程訪問相同的資源、不管如何調(diào)換調(diào)用順序,在主進程不去做任何同步,都會讓得到預(yù)期結(jié)果。這樣就是線程安全。多個線程同時訪問共享資源時,對共享資源的訪問不同會導致數(shù)據(jù)不一致或產(chǎn)生預(yù)期外的結(jié)果,這就是非線程安全。
簡單來說,線程安全就是你在主方法不管怎么調(diào)用某個多線程方法、調(diào)用幾次、什么順序調(diào)用,都能得到預(yù)期結(jié)果。
C#中創(chuàng)建和啟動線程的方法
在C#中,我們可以使用System.Threading命名空間下的Thread類來實現(xiàn)多線程編程。下面是一個簡單的示例,演示了如何創(chuàng)建和啟動一個線程:
using System;
using System.Threading;
class Program
{
static void Main()
{
// 創(chuàng)建一個Thread對象
Thread myThread = new Thread(new ThreadStart(Work));
// 啟動線程
myThread.Start();
// 主線程等待子線程結(jié)束
myThread.Join();
Console.WriteLine("線程結(jié)束");
}
// 在線程中執(zhí)行的方法
static void Work()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("子線程正在執(zhí)行,i = {0}", i);
Thread.Sleep(1000);
}
}
}
線程局部存儲
我們花費了大量篇幅來講并發(fā)訪問公共數(shù)據(jù)問題,前文提到的鎖構(gòu)造,信號構(gòu)造,無鎖構(gòu)造本質(zhì)上都是使用同步構(gòu)造,使得多線程在訪問公共數(shù)據(jù)時能安全的進行,然而有時我們會希望數(shù)據(jù)在線程間是隔離的,局部變量就能實現(xiàn)這個目的,但他們的生命周期總是那么短暫(隨代碼塊而釋放),我們期待更大作用域的隔離數(shù)據(jù),線程局部變量(thread-local storage,TLS)就可以實現(xiàn)這個目的。
注意
1、進程(應(yīng)用程序)會等待所有的前臺線程完成后再結(jié)束本工作;但是如果只剩下后臺線程,則會直接結(jié)束本工作,不會等待后臺線程完成后再結(jié)束本工作。
2、在任何時候我們都可以通過線程的IsBackground屬性改變線程的前后臺屬性
3、應(yīng)用程序的主線程以及使用Thread構(gòu)造的線程都默認為前臺線程
4、基于線程池ThreadPool功能創(chuàng)建的線程都默認為后臺線程
5、不涉及一些專用的,長時間保持運行的功能,都建議使用后臺線程。
6、I/O 異步線程數(shù),這個線程數(shù)限制的是執(zhí)行異步委托的線程數(shù)量