進(jìn)程與線程
進(jìn)程(Process)是計算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動膀跌,是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位号俐,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)皆怕。在早期面向進(jìn)程設(shè)計的計算機(jī)結(jié)構(gòu)中娃殖,進(jìn)程是程序的基本執(zhí)行實體值戳;在當(dāng)代面向線程設(shè)計的計算機(jī)結(jié)構(gòu)中,進(jìn)程是線程的容器炉爆。程序是指令堕虹、數(shù)據(jù)及其組織形式的描述,進(jìn)程是程序的實體芬首。
線程(英語:thread)是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位赴捞。它被包含在進(jìn)程之中,是進(jìn)程中的實際運(yùn)作單位郁稍。一條線程指的是進(jìn)程中一個單一順序的控制流螟炫,一個進(jìn)程中可以并發(fā)多個線程,每條線程并行執(zhí)行不同的任務(wù)艺晴。在Unix System V及SunOS中也被稱為輕量進(jìn)程(lightweight processes)昼钻,但輕量進(jìn)程更多指內(nèi)核線程(kernel thread),而把用戶線程(user thread)稱為線程封寞。
- 同一進(jìn)程中的多條線程將共享該進(jìn)程中的全部系統(tǒng)資源然评,如虛擬地址空間,文件描述符和信號處理等等狈究。但同一進(jìn)程中的多個線程有各自的調(diào)用棧(call stack)碗淌,自己的寄存器環(huán)境(register context),自己的線程本地存儲(thread-local storage)抖锥。
- 在早期面向進(jìn)程設(shè)計的計算機(jī)結(jié)構(gòu)中亿眠,進(jìn)程是程序的基本執(zhí)行實體;在當(dāng)代面向線程設(shè)計的計算機(jī)結(jié)構(gòu)中磅废,進(jìn)程是線程的容器纳像。在多線程OS中,線程是能獨立運(yùn)行的基本單位拯勉,因而也是獨立調(diào)度和分派的基本單位竟趾。由于線程很“輕”憔购,故線程的切換非常迅速且開銷小(在同一進(jìn)程中的)岔帽。在多線程OS中玫鸟,進(jìn)程不是一個可執(zhí)行的實體。
- 線程之間的通信更方便犀勒,同一進(jìn)程下的線程共享全局變量屎飘、靜態(tài)變量等數(shù)據(jù),而進(jìn)程之間的通信需要以通信的方式(IPC)進(jìn)行贾费。不過如何處理好同步與互斥是編寫多線程程序的難點钦购。
- 在引入線程的操作系統(tǒng)中,通常都是把進(jìn)程作為分配資源的基本單位铸本,而把線程作為獨立運(yùn)行和獨立調(diào)度的基本單位肮雨。
線程與進(jìn)程的區(qū)別可以歸納為以下4點:
1)地址空間和其它資源(如打開文件):進(jìn)程間相互獨立遵堵,同一進(jìn)程的各線程間共享箱玷。某進(jìn)程內(nèi)的線程在其它進(jìn)程不可見。
2)通信:進(jìn)程間通信IPC陌宿,線程間可以直接讀寫進(jìn)程數(shù)據(jù)段(如全局變量)來進(jìn)行通信——需要進(jìn)程同步和互斥手段的輔助锡足,以保證數(shù)據(jù)的一致性。
3)調(diào)度和切換:線程上下文切換比進(jìn)程上下文切換要快得多壳坪。
4)在多線程OS中舶得,進(jìn)程不是一個可執(zhí)行的實體。
- 進(jìn)程是資源分配的最小單位爽蝴,線程是程序執(zhí)行的最小單位沐批。
- 進(jìn)程有自己的獨立地址空間,每啟動一個進(jìn)程蝎亚,系統(tǒng)就會為它分配地址空間九孩,建立數(shù)據(jù)表來維護(hù)代碼段、堆棧段和數(shù)據(jù)段发框,這種操作非常昂貴躺彬。而線程是共享進(jìn)程中的數(shù)據(jù)的,使用相同的地址空間梅惯,因此CPU切換一個線程的花費遠(yuǎn)比進(jìn)程要小很多宪拥,同時創(chuàng)建一個線程的開銷也比進(jìn)程要小很多。
- 線程之間的通信更方便铣减,同一進(jìn)程下的線程共享全局變量她君、靜態(tài)變量等數(shù)據(jù),而進(jìn)程之間的通信需要以通信的方式(IPC)進(jìn)行葫哗。不過如何處理好同步與互斥是編寫多線程程序的難點犁河。
- 但是多進(jìn)程程序更健壯鳖枕,多線程程序只要有一個線程死掉,整個進(jìn)程也死掉了桨螺,而一個進(jìn)程死掉并不會對另外一個進(jìn)程造成影響宾符,因為進(jìn)程有自己獨立的地址空間
https://foofish.net/thread-and-process.html
堆和棧
棧 stack:
存放函數(shù)的參數(shù)值、局部變量灭翔,由編譯器自動分配釋放
堆heap:
是由new分配的內(nèi)存塊魏烫,由應(yīng)用程序控制,需要程序員手動利用delete釋放肝箱,如果沒有哄褒,程序結(jié)束后,操作系統(tǒng)自動回收
2煌张、因為堆的分配需要使用頻繁的new/delete呐赡,造成內(nèi)存空間的不連續(xù),會有大量的碎片
3骏融、堆的生長空間向上链嘀,地址越大,棧的生長空間向下档玻,地址越小
malloc/free 和new/delete 區(qū)別
相同點:都可用于申請動態(tài)內(nèi)存和釋放內(nèi)存
不同點:
簡單點說怀泊,malloc只分配指定大小的堆內(nèi)存空間,而new可以根據(jù)對象類型分配合適的堆內(nèi)存空間误趴,當(dāng)然還可以通過重載operator new 自定義內(nèi)存分配策略霹琼,其次還能夠構(gòu)造對象,free釋放對應(yīng)的堆內(nèi)存空間凉当,delete,先執(zhí)行對象的析構(gòu)函數(shù)枣申,在釋放對象所占空間。
malloc與free是C++/C 語言的標(biāo)準(zhǔn)庫函數(shù)看杭,new/delete 是C++的運(yùn)算符忠藤。malloc分配時的大小是人為計算的,返回類型是void*,使用時需要類型轉(zhuǎn)換泊窘,而new在分配時熄驼,編譯器能夠根據(jù)對象類型自動計算出大小,返回類型是指向?qū)ο箢愋偷闹羔樅姹浞庋b了sizeof和類型轉(zhuǎn)換功能瓜贾,實際上new分為兩步,第一步是通過調(diào)用operator new函數(shù)分配一塊合適携悯,原始的祭芦,未命名的內(nèi)存空間,返回類型也是void *,而且operator new可以重載憔鬼,可以自定義內(nèi)存分配策略龟劲,甚至不做內(nèi)存分配胃夏,甚至分配到非內(nèi)存設(shè)備上,而malloc無能為力昌跌,第二步仰禀,調(diào)用構(gòu)造函數(shù)構(gòu)造對象,new將調(diào)用constructor蚕愤,而malloc不能答恶;delete將調(diào)用destructor,而free不能