1.線程和多線程定義
線程是程序中一個單一的順序控制流程泡仗。進程內(nèi)有一個相對獨立的允扇、可調(diào)度的執(zhí)行單元耳高,是系統(tǒng)獨立調(diào)度和分派CPU的基本單位指令運行時的程序的調(diào)度單位癞蚕。在單個程序中同時運行多個線程完成不同的工作壕吹,稱為多線程著蛙。
2.線程和進程的區(qū)別
1.進程是資源分配的基本單位。所有與該進程有關(guān)的資源算利,都被記錄在進程控制塊PCB中册踩。以表示該進程擁有這些資源或正在使用它們。
2.進程也是搶占處理機的調(diào)度單位效拭,它擁有一個完整的虛擬地址空間暂吉。當進程發(fā)生調(diào)度時胖秒,不同的進程擁有不同的虛擬地址空間,而同一進程內(nèi)的不同線程共享同一地址空間慕的。
3.與進程相對應(yīng)阎肝,線程與資源分配無關(guān),它屬于某一個進程肮街,并與進程內(nèi)的其他線程一起共享進程的資源风题。
4.線程是進程中的一個單元,他是不能獨立運行的嫉父,他必須依賴某個進程沛硅。
3.使用多線程的原因
·使用線程可以把占據(jù)時間長的程序中的任務(wù)放到后臺去處理
·用戶界面的更新和交互是不能被阻塞的,耗時操作是不能放在主線程的
·當CPU是多核的時候绕辖,不同的進程可以實現(xiàn)并行摇肌,這樣就提高了程序的運行效率
·有些任務(wù)并不是連續(xù)的,需要等待仪际,比如網(wǎng)絡(luò)收發(fā)數(shù)據(jù)围小、用戶輸入等, 這些操作并不需要等到執(zhí)行完成,二是需要有變化才操作树碱。
4 多線程使用注意事項
4.1 開辟過多線程的問題
·系統(tǒng)需要為線程開辟存儲空間來管理他肯适,線程過多,會占用大量內(nèi)存成榜。
·線程是通過CPU來調(diào)度的框舔,過多的線程會加大CPU的負擔(dān),會增加耗電量伦连,還會讓機器發(fā)燙雨饺。
4.2 其他問題
·多個線程同時訪問同一數(shù)據(jù)的訪問,要確保數(shù)據(jù)的安全
·線程死鎖
5 線程的生命周期
1.線程創(chuàng)建后放到等待隊列中惑淳,等待CPU的調(diào)度额港,所以新建只有到就緒一種轉(zhuǎn)換。
2.就緒的是在等待的過程中歧焦,沒有被CPU執(zhí)行移斩,不會和其他的線程爭奪資源,所以會會變成阻塞狀態(tài)绢馍,只會在運行的狀態(tài)里切換向瓷。
3.運行的線程可以變成就緒、阻塞或者死亡的狀態(tài)舰涌,當時間片到后猖任,線程會進入到就緒狀態(tài),當某個線程得不到資源瓷耙,會被阻塞朱躺,當線程執(zhí)行完成后刁赖,線程會死亡。
4.線程死亡后长搀,不會保留線程相關(guān)信息宇弛,會釋放掉占用的內(nèi)存,所以死亡的線程是無法逆轉(zhuǎn)的源请。就不可以轉(zhuǎn)成其他幾種狀態(tài)枪芒。
6 線程間的通訊
線程間的通信機制實現(xiàn)起來則相對簡單,主要包括互斥鎖谁尸、條件變量舅踪、讀寫鎖和線程信號等。
6.1 互斥鎖
互斥鎖基本原理:互斥鎖以排他的方式防止數(shù)據(jù)被并發(fā)修改良蛮。當多個線程共享相同的內(nèi)存時硫朦,需要確保每個線程看到的數(shù)據(jù)是一樣的。如果是只讀背镇,那么一定是一樣的。如果是可讀可寫泽裳,在一個線程操作一個內(nèi)存區(qū)域時瞒斩,包含三個步驟,即讀出數(shù)據(jù)涮总,修改數(shù)據(jù)胸囱,寫回數(shù)據(jù)。如果該線程在沒有寫回數(shù)據(jù)前瀑梗,另一個線程來訪問同一個區(qū)域烹笔,如果是讀,得不到最新的數(shù)據(jù)狀態(tài)抛丽,如果是寫谤职,則會造成數(shù)據(jù)覆蓋等問題。[12306購票]
互斥鎖就兩個狀態(tài):開鎖(0)亿鲜,上鎖(1)允蜈。將某個共享資源和互斥鎖綁定后,對該共享資源的訪問操作如下:
A】在訪問資源前蒿柳,首先申請該互斥鎖饶套,如果在開鎖狀態(tài),則申請到該鎖對象垒探,并立即占有該鎖(鎖定)妓蛮。以防其他線程訪問修改此資源。如果該鎖處于鎖定狀態(tài)圾叼,默認阻塞等待蛤克。
B】原則上只有鎖定該互斥鎖的進程才能釋放此互斥鎖
6.2 條件變量
條件變量通信機制:
1捺癞、條件變量基本原理:條件變量的出現(xiàn),可以彌補互斥鎖的缺陷咖耘,有些問題僅僅靠互斥鎖無法解決翘簇。但是條件變量不能單獨使用,必須配合互斥鎖一起實現(xiàn)對資源的互斥訪問
6.3 讀寫鎖
1儿倒、讀寫鎖基本原理:在對數(shù)據(jù)的讀寫操作時版保,往往是讀占主要部分。為了滿足當前能夠允許多個讀出夫否,但只允許一個寫入的需求彻犁。線程提供了讀寫鎖來實現(xiàn)。讀寫鎖基本原則如下:
A】如果有其他線程讀數(shù)據(jù)凰慈,則允許其他線程執(zhí)行讀操作汞幢,但是不允許寫操作。
B】如果有其他線程申請了寫鎖微谓,則其他線程既不能申請讀鎖森篷,也不能申請寫鎖
6.4 線程信號:
線程是一種輕量級的進程,因此進程的信號同樣適用于線程豺型。不過相對于進程信號仲智,線程擁有與信號相關(guān)的私有數(shù)據(jù)——線程信號掩碼,則就決定了線程在信號操作時具有以下特性:
A】每個線程可以先別的線程發(fā)送信號姻氨,pthread_kill()函數(shù)用來完成這一操作钓辆。
B】每個線程都可以設(shè)置自己的阻塞集合。pthread_sigmask()用來完成這一操作肴焊。類似于進程中的sigprocmask()函數(shù)前联。主進程創(chuàng)建出來的線程繼承主進程的掩碼。
C】每個線程需要設(shè)置針對某信號的處理方式娶眷,但同一個進程中對某信號的處理方式只能有一個有效似嗤,即最后一次設(shè)置的處理方式。即在所有的線程里茂浮,同一信號在任何線程里的對該信號的處理一定相同
D】如果別的進程向當前進程發(fā)來一個信號双谆,具體由哪個線程去處理,是未知的席揽。
注:如果有不準確的地方顽馋,歡迎大家來吐槽。QQ:1392984568 一米陽光 (iOS 修煉者 )