OS / 进程和线程的区别和联系
一、理論講解
進程是資源分配的最小單位,線程是CPU調度的最小單位。
二、通粗講解
作者:人民郵電出版社
 鏈接:https://www.zhihu.com/question/25532384/answer/1598653960
 來源:知乎
 著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
1、什么是線程呢?
網上一般是這樣定義的:線程(thread)是操作系統能夠進行運算調度的最小單位,它被包含在進程之中,是進程中的實際運作單位。
這么說,你聽懂了嗎?我覺得這樣的定義純粹是自說自話:新手看完了一臉懵,老鳥看完了不以為然。我們還是用“非專業”的外行話來解釋一下吧。
假設你經營著一家物業管理公司。最初,業務量很小,事事都需要你親力親為。給老張家修完暖氣管道,立馬再去老李家換電燈泡——這叫單線程,所有的工作都得順序執行。
后來業務拓展了,你雇傭了幾個工人,這樣,你的物業公司就可以同時為多戶人家提供服務了——這叫多線程,你是主線程。
工人們使用的工具,是物業管理公司提供的,這些工具由大家共享,并不專屬于某一個人——這叫多線程資源共享。
工人們在工作中都需要管鉗,可是管鉗只有一把——這叫沖突。解決沖突的辦法有很多,比如排隊等候、等同事用完后的微信通知等——這叫線程同步。
你給工人布置任務——這叫創建線程。之后你還得要告訴他,可以開始了,不然他會一直停在那兒不動——這叫啟動線程(start)。
如果某個工人(線程)的工作非常重要,你(主線程)也許會親自監工一段時間,如果不指定時間,則表示你會一直監工到該項工作完成——這叫線程參與(join)。
業務不忙的時候,你就在辦公室喝喝茶。下班時間一到,你群發微信,所有的工人不管手頭的工作是否完成,都立馬撂下工具,跟你走人。因此如果有必要,你得避免不要在工人正忙著的時候發下班的通知——這叫線程守護屬性設置和管理(daemon)。
再后來,你的公司規模擴大了,同時為很多生活社區服務,你在每個生活社區設置了分公司,分公司由分公司經理管理,運營機制和你的總公司幾乎一模一樣——這叫多進程,總公司叫主進程,分公司叫子進程。
總公司和分公司,以及各個分公司之間,工具都是獨立的,不能借用、混用——這叫進程間不能共享資源。各個分公司之間可以通過專線電話聯系——這叫管道。各個分公司之間還可以通過公司公告欄交換信息——這叫進程間共享內存。另外,各個分公司之間還有各種協同手段,以便完成更大規模的作業——這叫進程間同步。分公司可以跟著總公司一起下班,也可以把當天的工作全部做完之后再下班——這叫守護進程設置。
2、進程有什么用?
進程可以說是一個“執行中的程序”。程序是指令、數據及其組織形式的描述,是一個沒有生命的實體,只有處理器賦予程序生命時(操作系統執行之),它才能成為一個活動的實體,我們稱其為進程。
有了線程技術,我們就可以在一個進程中創建多個線程,讓它們在“同一時刻”分別去做不同的工作了。這些線程共享同一塊內存,線程之間可以共享對象、資源,如果有沖突或需要協同,還可以隨時溝通以解決沖突或保持同步。
不過,多線程技術不是萬金油,它有一個致命的缺點:在一個進程內,不管你創建了多少線程,它們總是被限定在一顆CPU內,或者多核CPU的一個核內。這意味著,多線程在宏觀上是并行的,在微觀上則是分時切換串行的,多線程編程無法充分發揮多核計算資源的優勢。這也是使用多線程做任務并行處理時,線程數量超過一定數值后,線程越多速度反倒越慢的原因。
多進程技術正好彌補了多線程編程的不足,我們可以在每一顆CPU上,或者多核CPU的每一個核上啟動一個進程,如果有必要,還可以在每個進程內再創建適量的線程,最大限度地使用計算資源解決問題。因為不在同一塊內存區域內,和線程相比,進程間的資源共享、通信、同步等,都要麻煩得多,受到的限制也更多。
三、站在 OS 角度
站在Linux 中線程和進程基本沒有區別呢,因為從 Linux 內核的角度來看,并沒有把線程和進程區別對待。
我們知道系統調用 fork() 可以新建一個子進程,函數 pthread() 可以新建一個線程。但無論線程還是進程,都是用 task_struct 結構表示的,唯一的區別就是共享的數據區域不同。
換句話說,線程看起來跟進程沒有區別,只是線程的某些數據區域和其父進程是共享的,而子進程是拷貝副本,而不是共享。就比如說,mm 結構和 files 結構在線程中都是共享的,我畫兩張圖你就明白了:
所以說,我們的多線程程序要利用鎖機制,避免多個線程同時往同一區域寫入數據,否則可能造成數據錯亂。
那么你可能問,既然進程和線程差不多,而且多進程數據不共享,即不存在數據錯亂的問題,為什么多線程的使用比多進程普遍得多呢?
因為現實中數據共享的并發更普遍呀,比如十個人同時從一個賬戶取十元,我們希望的是這個共享賬戶的余額正確減少一百元,而不是希望每人獲得一個賬戶的拷貝,每個拷貝賬戶減少十元。
當然,必須要說明的是,只有 Linux 系統將線程看做共享數據的進程,不對其做特殊看待,其他的很多操作系統是對線程和進程區別對待的,線程有其特有的數據結構,我個人認為不如 Linux 的這種設計簡潔,增加了系統的復雜度。
在 Linux 中新建線程和進程的效率都是很高的,對于新建進程時內存區域拷貝的問題,Linux 采用了 copy-on-write 的策略優化,也就是并不真正復制父進程的內存空間,而是等到需要寫操作時才去復制。所以 Linux 中新建進程和新建線程都是很迅速的。
?
?
其他:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html
參考:https://zhuanlan.zhihu.com/p/105086274
(SAW:Game Over!)
總結
以上是生活随笔為你收集整理的OS / 进程和线程的区别和联系的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: OS / 几个常用的操作系统进程调度算法
- 下一篇: OS / 线程的 3 种实现方式(内核级
