為什么要引入線程?線程為什么能彌補進程的缺點


首先我們需要明白,線程與進程一樣,線程和進程會被os統一調度,所以所有的線程和進程都是一起並發運行的,如果線程不是並發的,是不可能實現程序的多線任務的。
有了線程以后,凡是程序涉及到多線任務時,都使用多線程來實現,使用多線程來實現時,線程間的切換和數據通信的開銷非常低,正因為開銷非常低,因此線程還有另一個名稱,叫”輕量級的進程“。
總結的講,說白了線程就是為了多線任務而生的,多線程的多線二字,不就是多線任務的多線二字嗎。
疑問:使用線程來實現時,線程也需要切換和通信,這不跟進程一樣嗎?為什么線程就能降低切換和通信的開銷呢?

為什么線程切換的開銷很低

使用多進程來實現程序的多線任務,多線並發運行時,涉及到的是進程間的切換,我們前面就說過,進程間切換時開銷非常大。
但是使用多線程來實現多線任務,由於線程本質上它只是程序(進程)的一個函數,只不過線程函數與普通函數的區別是,普通函數時單線的運行關系,而線程函數被注冊為線程后,是多線並發運行,如圖所示。
普通函數與線程函數
對於普通函數來說,只有當相互調動時才會涉及函數間的切換,但是對於線程函數來說,只要運行的時間片到了就會切換,但是不管是那種函數間的切換,進程自己函數的切換只是進程內部的事情,不涉及進程間切換,函數切換當然也需要開銷,但是這些開銷相比進程間就省去了進程間切換的巨大開銷。
當然如果是不同進程的線程之間需要切換的話,還是會涉及到進程間的切換的,但是不管怎么說,線程的出現,至少為程序內部多線任務之間的切換,省去了大筆的進程切換所導致“資源開銷”。

為什么線程間數據通信的開銷很低

線程的本質就是函數,請問大家函數之間如果想要數據共享(通信)的話,應該怎么辦?
函數間通信有兩種方式:
(1)具有相互調用關系函數來說
使用函數傳參來通信。
(2)對於沒有調用關系的函數來說
使用全局變量來通信。
A函數一一>全變變量一一>B函數
所以說全局變量的作用是什么?
就是用來實現無調用關系的函數間通信的。進程中所有的線程函數除了相互並發運行外,沒有調用關系,所以線程函數間想要數據共享的話,就使用全局變量來通信。

從這里可以看出,進程內部的線程間進行數據共享非常容易,使用全局變量即可,根本不需要調用什么os提供的通信機制,所以線程間通信的開銷自然就非常的低。
進程間的通信需要調用操作系統提供的相關函數,這些函數運行需要開銷。

那么疑問來了,線程切換就不需要開銷嗎?
剛說過,線程的切換其實就是函數間的切換(保存函數狀態在棧中),切換的開銷來說,已經非常小了。

是不是有了線程后,進程是不是就不需要了

線程是不可能完全替代掉進程的,只有在多線任務時會替代進程,但是運行新程序時,還是必須通過創建子進程來實現
通過前面的講解,我們知道線程的本質是函數,函數運行需要內存空間,這個內存空間怎么來,事實上線程所需內存空間就是進程的內存空間,因此線程的運行時依賴於進程,如果沒有進程所提供的內存空間這個資源,線程根本無法運行
換句話說,線程作為函數,只是進程的一個部分而己,線程是不可能脫離進程而獨立存在。
所以同一個進程中的所有線程,都是運行在進程空間中的,換句話說同一個進程中所有線程共享相同的進程空間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM