日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

全面总结:进程与线程

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 全面总结:进程与线程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先,進程和線程的區別:

根本區別:進程是操作系統資源分配的基本單位,而線程是任務調度和執行的基本單位

在開銷方面:每個進程都有獨立的地址空間,進程之間的切換會有較大的開銷;線程可以看做輕量級的進程,同一進程內的多個線程共享代碼和數據空間,但每個線程都有自己獨立的運行棧和程序計數器(PC),且線程的創建、銷毀以及線程之間切換的開銷較小。

線程之間的通信更方便,同一進程下的線程共享全局變量、靜態變量等數據,而進程之間的通信需要以通信的方式(IPC)進行。

多進程程序更健壯,多線程程序只要有一個線程死掉,整個進程也死掉了,而一個進程死掉并不會對另外一個進程造成影響,因為進程有自己獨立的地址空間。

?

進程三態狀態裝換圖

?

?

?

就緒態只需要等待處理機(CPU)

阻塞態可能在等待輸入輸出,即使分配給處理機也是徒勞

調度進程,只需要等待就緒隊列里的進程,因為阻塞狀態可以轉換到就緒隊列里去

?

就緒原因:

??? 缺少cpu

?

阻塞原因

?1.內存資源緊張

2.? 無就緒隊列,處理機空閑

3 .I/O速度比處理機速度慢的多,可能出現全部進程阻塞等待I/O。

解決方法

l? 交換技術:換出一部分暫時不能運行的進程(阻塞進程)到外存(只換出程序和數據,PCB不換出去),以騰出內存空間,可以調用新進程來執行。

l? 虛擬存儲技術:每個進程只能裝入一部分程序和數據

?

?

掛起原因:

????? ?掛起:進程被交換到外存,狀態變為掛起狀態

?進程掛起的原因

1.進程全部阻塞,處理機空閑。

2.系統負荷過重,內存空間緊張。(讓其他進程先執行完)

3.操作系統的需要。操作系統可能需要掛起后臺進程或一些服務進程,或者某些可能導致故障的進程。

?4.終端用戶請求。

5父進程的需求。

?掛起進程的特征

l? 不能立即執行

l? 可能是等待某事件發生,若是,則阻塞條件獨立于掛起條件,即使阻塞事件發生,該進程也不能執行。

n? 阻塞和掛起沒有聯系。

n? 如果A進程現在要求輸入數據,此時A進程屬于阻塞狀態,在選擇掛起進程的時候,可能先選擇阻塞進程(A進程),此時A進程掛起,正在輸入數據,輸入到內存緩沖區內。當數據輸完了,向處理機發送命令數據已經輸入完成,阻塞事件解除,但實際上還是掛起,所以仍是掛起態。

l? 使之掛起的進程為:自身、父進程、OS。

l? 只有掛起它的進程才能使之由掛起狀態轉換為其他狀態。

?

? 阻塞與掛起

l? 進程是否等待時間:阻塞與否。

l? 進程是否被換出內存:掛起與否。

?

4.4? 四種狀態組合

l? 就緒:進程在內存,準備執行。

l? 阻塞:進程在內存,等待事件。

l? 就緒/掛起:進程在外存,只要調入內存即可執行。

l? 阻塞/掛起:進程在外存,等待事件。

?

? 處理機可調度執行的進程有兩種

l? 新創建的進程

l? 或換入一個以前掛起的進程

通常為避免增加系統負載,系統會換入一個以前掛起的進程執行。

?

4.6? 具有掛起狀態的進程狀態轉換

?

l? 阻塞 → 阻塞/掛起:OS通常將阻塞進程換出,以騰出內存空間

l? 阻塞/掛起→ 就緒/掛起:當阻塞/掛起進程等待的事件發生時,可以將其轉換為就緒/掛起。

l? 就緒/掛起→ 就緒:OS需要調入一個進程執行。

l? 就緒 → 就緒/掛起:一般,OS掛起阻塞進程。但是有時也會掛起就緒進程,釋放足夠的內存空間。

l? 新 → 就緒/掛起(新→ 就緒):新進程創建后,可以插入到就緒隊列或就緒,掛起隊列,若無足夠的內存分配給新進程,則需要新→ 就緒/掛起。

----------------------------------------------------------------------------------------------------------------------------------------------------------

所以,我們必須知道,進程為何掛起?因為內存空間資源緊張,所以要把阻塞或者就緒的進程從內存切換至外存,釋放內存空間;所以說阻塞或者就緒的進程是在內存中的,只是沒有占用CPU的資源;

還有一個問題就是,我們知道,進程一般是自己阻塞自己,等待某個時間的發生;當某個事件發生時,進程只能由其他進程或者OS喚醒,這是為什么?顯然,進程阻塞它就停止運行,釋放處理機資源了,就是說它自己和睡著了差不多,你怎么讓一個睡著的人自己叫醒自己呢?很好理解。

----------------------------------------------------------------------------------------------------------------------------------------------------------

接下來,我們來看一下進程的創建、執行、等待、終止過程

具體的流程如下。

我們知道,操作系統通過fork()調用來創建子進程。系統最初的初始進程(或者稱為root進程)為init進程。

當我們創建子進程之后涉及到父子進程之間的進程地址空間的復制,一般來說,我們會在子進程創建的時候將父進程的地址空間包括地址空間里的代碼、數據和堆棧等等資源全部拷貝一份給子進程,添加修改頁表項。當子進程在通過exec()系統調用執行的時候,會去打開新的代碼文件,將原始的父進程拷貝過來的內容覆蓋掉,執行新的內容。這就造成一個問題,什么問題?既然子進程對于父進程的內容沒有執行意義,而且拷貝會占用系統資源,那何必要進行創建時的拷貝工作呢?

所以,我們引入一種COPY ON WRITE 技術(寫時覆蓋),就是在創建的時候僅僅修改頁表項,拷貝所需的原始數據資源。當我們的子進程在執行的時候需要進行寫操作的時候,才進行相應的拷貝和覆蓋。因為如果子進程僅僅只是讀取操作的話,完全沒有拷貝的需要,直接讀取父進程地址空間的內容即可。

當進程調用exec()的時候不一定是立刻運行的,理論上是進行running。但是由于會進行磁盤文件數據的換入操作,所以當前進程還是會阻塞,等待換入完成則就緒---》執行。

進程的等待:當子進程通過exit()退出的時候,系統會釋放掉其用戶空間的資源,但是其存在于內核中的資源(例如PCB)卻沒有回收(因為系統內核通過進程的PCB來對相應的進程做出處理,PCB存在于內核空間的相應的進程執行隊列)。

那么怎么辦呢?那肯定是通過其父進程來進行回收。因此父進程在其子進程通過exit()退出后,通過調用wait()來得到子進程的終止狀態信息,然后進行子進程PCB等資源的相應回收處理。

在子進程調用exit()到父進程調用wait()之間的狀態,稱作“”僵尸狀態“”。

還有一種情況就是,當子進程終止時,其父進程也終止了,那么由于系統的init進程會定期掃描系統的進程表來篩選出僵尸進程,并做相應的回收處理。

考慮當父進程終止,但其子進程還未終止的情況。此時子進程稱為“”孤兒進程“”,由init進程收養。

-------------------------------------------------------------------進程同步互斥--------------------------------------------------------------------

? ?補充一個坑爹坑爹坑爹坑爹的問題:系統如何將一個信號通知到進程?

? ? ?前面講過信號了,為什么又問一遍?這個問題有什么特殊的地方么??
? ? ?內核給進程發送信號,是在進程所在的進程表項的信號域設置對應的信號的位。

? ? ? ? 更多:http://blog.csdn.net/joejames/article/details/37960873?

?

-------------------------------------------------------------------線程同步互斥--------------------------------------------------------------------

  linux系統的通訊機制,主要是指進程間通訊,其實通訊就是進程同步的手段。

????? 這里要說的linux系統的同步機制是講線程間的同步。?


  互斥量?
  首先是最基礎的加鎖原語,互斥量。既確保同一時間只有一個線程訪問數據,通過在訪問共享資源前對互斥量加鎖,阻塞其他試圖再次加鎖的線程知道互斥鎖被釋放。互斥的具體實現有多種方法,例如開關中斷,使用原子的機器指令。?
  讀寫鎖?
  與互斥量類似,不過允許更高的并行性。讀寫鎖有三種狀態,讀模式的加鎖,寫模式的加鎖,不加鎖狀態。一次只有一個線程可以占有寫模式的讀寫鎖,但是可以多個線程可以同時占用讀模式的讀寫鎖。既讀模式下可以共享,寫模式下互斥。一般一個線程試圖以讀模式獲取鎖時,讀寫鎖通常會阻塞隨后的讀模式鎖請求。?
  條件變量?
  互斥量是加鎖原語,條件變量屬于等待原語,用于等待某個條件成立后喚醒阻塞的線程。條件變量與互斥量一起使用,條件本身由互斥量保護。Java Object內置了條件變量wait(),notify(),notifyAll()。   ?
  pthread_cond_wait(),pthread_cond_signal(),pthread_cond_broadcast(Unix),從函數的命名就可以看出其大致作用。?
  根據陳碩的總結,條件變量的正確使用方式:?
  對于wait端:?
  1.必須與mutex一起使用。?
  2.在mutex已上鎖時才能調用wait()。?
  3.把判斷布爾條件和wait()放到while循環中。?
  第三個條件主要是為了防止spurious wakeup,既虛假喚醒。因為pthread_conf_wait能被除了pthread_cond_signal(),pthread_cond_broadcast外的其他信號喚醒。需要再wait后再次檢查,同時也是為了避免錯過一次條件變量后永遠的等待下去。?
  對于signal端:?
  1.一定不要在mutex已經上鎖的情況下調用signal。?
  2.在signal之前一般要修改布爾表達式。?
  3.修改布爾表達式通常用mutex保護。?
  4.注意區分signal和broadcast:“broadcast通常用于表明狀態變化,signal通常用于表示資源可用”。?
  自旋鎖?
  自旋鎖與互斥量類似,但它不是通過休眠使進程阻塞,二是在獲取鎖之前一直處于忙等。既一直占用CPU資源直到鎖被釋放。?
  屏障?
  屏障主要用于多個線程之間的并行工作的協調。屏障允許每個線程等待,直到所有的合作線程都達到某個點,然后從該點繼續執行。?
  信號量?
  這個在《unix環境高級編程》中沒有提及,在《操作系統》中有論述。?
  信號量可作用與進程間合作,以及多線程的同步。?
  一個進程可以被迫在某一個位置停止,直到接收到某一個信號。為了發信號,需要使用一個稱為信號量的特殊變量,可以看做一個具有整數值得變量。其中只允許信號量取0和1的稱為二元信號量。非二元信號量常稱為計數信號量或一般信號量。?
  一般在信號量上定義三個操作:?
  1.一個信號量可以初始化成非負數。?
  2.semWait操作使信號量減1。如果值變為負數,則執行semWait的進程或線程被阻塞,否則繼續執行。?
  3.semSignal操作使信號量加1。如果值<=0,則被semWait阻塞的進程被解除阻塞。?
  信號量需要隊列保存阻塞在信號量上等待的進程。至于進程按什么順序移除,最公平的是先進先出,采用此策略的為強信號量。沒有規定順序的為弱信號量。?
  互斥量和二元信號量的主要區別在于互斥量的加鎖和解鎖必須由同一線程分別對應使用,信號量可以由一個線程釋放,另一個線程得到。至于用于互斥和用于同步的說法,十分牽強。?
  陳碩關于信號量的建議是不用。?
  因為可用條件變量加互斥量完全代替,另外還需要擔心計數值需要和自己的數據長度常常保持一致的問題。?
  死鎖?
  死鎖大概已經被講爛了,我也不想再搬運了。堅持使用Scoped Locking,死鎖的時候好檢測。?

---------------------------------------------------------------多線程和多進程的區別---------------------------------------------------------------------

多線程和多進程的區別(重點 必須從cpu調度,上下文切換,數據共享,多核cup利用率,資源占用,等等各方面回答,然后有一個問題必須會被問到:哪些東西是一個線程私有的?答案中必須包含寄存器,否則悲催)

  區別的意思是優缺點吧。?
  ?
  多線程:

  • 高效的內存共享,數據共享
  • 較輕的上下文切換開銷,不用切換地址空間,不用更改CR3寄存器,不用清空TLB。
  • 創建銷毀切換比較簡單

    多進程:

  • 更強的容錯性,不會一阻全阻,一個進程崩潰不會整個系統崩潰。

  • 更好的多核伸縮性,進程的使用將許多內核資源(如地址空間,頁表,打開的文件)隔離,在多核系統上的可伸縮性強于多線程程序

    在多核利用率上,多進程和多線程同樣可以提高多核利用率。?
    其實對于創建和銷毀,上下文切換,其實在Linux系統下差別不大,Window下有較大差別。?
    綜上,多進程和多線程的最主要的區別就在資源共享,隔離問題。如果工作使用的內存較大,使用多線程可以避免CPU cache的換入換出,影響性能。

    線程私有

  • ID,每個線程都有自己的ID作為進程中唯一的表述。

  • 一組寄存器值,用來保存狀態
  • 各自的堆棧
  • 錯誤返回碼,防止錯誤還未被處理就被其他線程修改。
  • 信號屏蔽碼,每個線程感興趣的信號不同。
  • 優先級
  • 共享的:進程的代碼段,公有數據,進程打開的文件描述符,全局內存,進程的棧,堆內存等。

總結

以上是生活随笔為你收集整理的全面总结:进程与线程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。