计算机基础:程序、进程、线程
進(jìn)程、線程、多線程相關(guān)總結(jié)
一、說(shuō)說(shuō)概念
1、進(jìn)程(process)
狹義定義:進(jìn)程就是一段程序的執(zhí)行過(guò)程。
廣義定義:進(jìn)程是一個(gè)具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合的一次運(yùn)行活動(dòng)。它是操作系統(tǒng)動(dòng)態(tài)執(zhí)行的基本單元,在傳統(tǒng)的操作系統(tǒng)中,進(jìn)程既是基本的分配單元,也是基本的執(zhí)行單元。
簡(jiǎn)單的來(lái)講進(jìn)程的概念主要有兩點(diǎn):第一,進(jìn)程是一個(gè)實(shí)體。每一個(gè)進(jìn)程都有它自己的地址空間,一般情況下,包括文本區(qū)域(text region)、數(shù)據(jù)區(qū)域(data region)和堆棧(stack region)。文本區(qū)域存儲(chǔ)處理器執(zhí)行的代碼;數(shù)據(jù)區(qū)域存儲(chǔ)變量和進(jìn)程執(zhí)行期間使用的動(dòng)態(tài)分配的內(nèi)存;堆棧區(qū)域存儲(chǔ)著活動(dòng)過(guò)程調(diào)用的指令和本地變量。第二,進(jìn)程是一個(gè)“執(zhí)行中的程序”。程序是一個(gè)沒(méi)有生命的實(shí)體,只有處理器賦予程序生命時(shí),它才能成為一個(gè)活動(dòng)的實(shí)體,我們稱其為進(jìn)程。
進(jìn)程狀態(tài):進(jìn)程有三個(gè)狀態(tài),就緒、運(yùn)行和阻塞。就緒狀態(tài)其實(shí)就是獲取了除cpu外的所有資源(等待cpu資源),只要處理器分配資源就可以馬上執(zhí)行。就緒狀態(tài)有排隊(duì)序列什么的,排隊(duì)原則不再贅述。運(yùn)行態(tài)就是獲得了處理器分配的資源,程序開(kāi)始執(zhí)行。阻塞態(tài),當(dāng)程序條件不夠時(shí)候,需要等待條件滿足時(shí)候才能執(zhí)行,如等待i/o操作時(shí)候,此刻的狀態(tài)就叫阻塞態(tài)。
2、程序
說(shuō)起進(jìn)程,就不得不說(shuō)下程序。先看定義:程序是指令和數(shù)據(jù)的有序集合,其本身沒(méi)有任何運(yùn)行的含義,是一個(gè)靜態(tài)的概念。而進(jìn)程則是在處理機(jī)上的一次執(zhí)行過(guò)程,它是一個(gè)動(dòng)態(tài)的概念。這個(gè)不難理解,其實(shí)進(jìn)程是包含程序的,進(jìn)程的執(zhí)行離不開(kāi)程序,進(jìn)程中的文本區(qū)域就是代碼區(qū),也就是程序。
3、線程
通常在一個(gè)進(jìn)程中可以包含若干個(gè)線程,當(dāng)然一個(gè)進(jìn)程中至少有一個(gè)線程,不然沒(méi)有存在的意義。線程可以利用進(jìn)程所擁有的資源,在引入線程的操作系統(tǒng)中,通常都是把進(jìn)程作為分配資源的基本單位,而把線程作為獨(dú)立運(yùn)行和獨(dú)立調(diào)度的基本單位,由于線程比進(jìn)程更小,基本上不擁有系統(tǒng)資源,故對(duì)它的調(diào)度所付出的開(kāi)銷就會(huì)小得多,能更高效的提高系統(tǒng)多個(gè)程序間并發(fā)執(zhí)行的程度。
4、多線程
在一個(gè)程序中,這些獨(dú)立運(yùn)行的程序片段叫作“線程”(Thread),利用它編程的概念就叫作“多線程處理”。多線程是為了同步完成多項(xiàng)任務(wù),不是為了提高運(yùn)行效率,而是為了提高資源使用效率來(lái)提高系統(tǒng)的效率。線程是在同一時(shí)間需要完成多項(xiàng)任務(wù)的時(shí)候?qū)崿F(xiàn)的。
最簡(jiǎn)單的比喻多線程就像火車的每一節(jié)車廂,而進(jìn)程則是火車。車廂離開(kāi)火車是無(wú)法跑動(dòng)的,同理火車也不可能只有一節(jié)車廂。多線程的出現(xiàn)就是為了提高效率。
二、說(shuō)說(shuō)區(qū)別
1、進(jìn)程與線程的區(qū)別:
進(jìn)程和線程的主要差別在于它們是不同的操作系統(tǒng)資源管理方式。進(jìn)程有獨(dú)立的地址空間,一個(gè)進(jìn)程崩潰后,在保護(hù)模式下不會(huì)對(duì)其它進(jìn)程產(chǎn)生影響,而線程只是一個(gè)進(jìn)程中的不同執(zhí)行路徑。線程有自己的堆棧和局部變量,但線程之間沒(méi)有單獨(dú)的地址空間,一個(gè)線程死掉就等于整個(gè)進(jìn)程死掉,所以多進(jìn)程的程序要比多線程的程序健壯,但在進(jìn)程切換時(shí),耗費(fèi)資源較大,效率要差一些。但對(duì)于一些要求同時(shí)進(jìn)行并且又要共享某些變量的并發(fā)操作,只能用線程,不能用進(jìn)程。
1) 簡(jiǎn)而言之,一個(gè)程序至少有一個(gè)進(jìn)程,一個(gè)進(jìn)程至少有一個(gè)線程.
2) 線程的劃分尺度小于進(jìn)程,使得多線程程序的并發(fā)性高。
3) 另外,進(jìn)程在執(zhí)行過(guò)程中擁有獨(dú)立的內(nèi)存單元,而多個(gè)線程共享內(nèi)存,從而極大地提高了程序的運(yùn)行效率。
4) 線程在執(zhí)行過(guò)程中與進(jìn)程還是有區(qū)別的。每個(gè)獨(dú)立的線程有一個(gè)程序運(yùn)行的入口、順序執(zhí)行序列和程序的出口。但是線程不能夠獨(dú)立執(zhí)行,必須依存在應(yīng)用程序中,由應(yīng)用程序提供多個(gè)線程執(zhí)行控制。
5) 從邏輯角度來(lái)看,多線程的意義在于一個(gè)應(yīng)用程序中,有多個(gè)執(zhí)行部分可以同時(shí)執(zhí)行。但操作系統(tǒng)并沒(méi)有將多個(gè)線程看做多個(gè)獨(dú)立的應(yīng)用,來(lái)實(shí)現(xiàn)進(jìn)程的調(diào)度和管理以及資源分配。這就是進(jìn)程和線程的重要區(qū)別。
三、說(shuō)說(shuō)優(yōu)缺點(diǎn)
線程和進(jìn)程在使用上各有優(yōu)缺點(diǎn):線程執(zhí)行開(kāi)銷小,但不利于資源的管理和保護(hù);而進(jìn)程正相反。同時(shí),線程適合于在SMP(多核處理機(jī))機(jī)器上運(yùn)行,而進(jìn)程則可以跨機(jī)器遷移。
四、總結(jié)
入職第一天閑的無(wú)聊,參考下別人的總結(jié)自己也簡(jiǎn)單總結(jié)了下。知道以上的基本面試夠用了,至于進(jìn)程、線程的細(xì)節(jié),底層構(gòu)成,調(diào)度等問(wèn)題是操作系統(tǒng)的東西。我就不詳述了。
五、實(shí)例
1、多線程寫(xiě)日志,涉及到單例模式,異步寫(xiě)
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks;namespace ConsoleApplication1 {class Program{static void Main(string[] args){Thread t1 = new Thread(Working);t1.Name = "Thread1";Thread t2 = new Thread(Working);t2.Name = "Thread2";Thread t3 = new Thread(Working);t3.Name = "Thread3";// 依次啟動(dòng)3個(gè)線程。t1.Start();t2.Start();t3.Start();Console.ReadKey();}// 每個(gè)線程都同時(shí)在工作static void Working(){// 模擬1000次寫(xiě)日志操作for (int i = 0; i < 1000; i++){// 異步寫(xiě)文件logger.Write(Thread.CurrentThread.Name + " writes a log: " + i + ", on " + DateTime.Now.ToString() + ".\n");}// 做一些其它的事件for (int i = 0; i < 100; i++) { }}}public class logger{private Queue<Action> _queue;//寫(xiě)日志線程private Thread _loggingThread;//信號(hào)器private ManualResetEvent _hasNew;// 使用單例模式,保持一個(gè)Logger對(duì)象private static readonly logger _logger = new logger();private static logger GetInstance(){/* 不安全代碼lock (locker) {if (_logger == null) {_logger = new Logger();}}*/return _logger;}private logger(){_queue = new Queue<Action>();_hasNew = new ManualResetEvent(false);_loggingThread = new Thread(Process);_loggingThread.IsBackground = true;_loggingThread.Start();}private void Process(){while (true){//等待信號(hào),阻塞線程_hasNew.WaitOne();//接收到信號(hào),信號(hào)關(guān)閉,重置_hasNew.Reset();Thread.Sleep(100);Queue<Action> queueCopy;lock (_queue){queueCopy = new Queue<Action>(_queue);_queue.Clear();}foreach (var action in queueCopy){action();}}}private void WeiteLog(string content){lock (_queue){_queue.Enqueue(() => File.AppendAllText("log.txt", content));}_hasNew.Set();}public static void Write(string content){Task.Run(() => GetInstance().WeiteLog(content));}}}?
總結(jié)
以上是生活随笔為你收集整理的计算机基础:程序、进程、线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Python】分享几个好用到爆的Pyt
- 下一篇: 【机器学习】机器学习必知概念