1.定義python
線程就像一條工廠車間裏的流水線,一個車間裏能夠用不少流水線,來執行生產每一個零部件的任務。nginx
因此車間能夠看做是進程,流水線能夠看做是線程。(進程是資源單位,線程是執行單位)程序員
啓動一個進程,至少該進程內有一個線程(主線程,「父線程」)算法
2.爲何要用線程? 編程
比喻:一個車間須要至少有一條生產線,若是主生產線生產汽車的發動機,若是還想要生產變速箱,底盤,是新開一個車間來生產,仍是再開2個生產線進行生產快呢? 而且三大件之間須要彼此共享 合做,因此多個流水線生產很重要!windows
總結:線程的特色多線程
1.同一進程下的多個線程共享該進程內的資源併發
2.開啓一個線程的開銷遠遠小於開啓一個進程ide
ps:建立進程須要申請空間,而且該空間內至少一條流水線,建立線程無需申請空間,因此開銷小。性能
3.怎麼用線程?
涉及線程的建立和使用場景,請見併發編程多線程--實踐部分。
比喻:多個車間都是資源單位,爲了生產的流水線,是一種資源競爭關係;而同一個車間的流水線,則是協同關係,協同配合,資源共享,達標完成車間主任部署的生產任務。
總結:
進程之間的關係是競爭關係,而線程之間是協做關係。
1.Threads share the address space of the process that created it; processes have their own address space.
線程共享建立它的進程的地址空間; 進程有本身的地址空間。
2.Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
線程能夠直接訪問其進程的數據段; 進程擁有本身父進程數據段的副本。
3.Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
線程能夠直接與其進程的其餘線程通訊; 進程必須使用進程間通訊來與兄弟進程通訊。
4.New threads are easily created; new processes require duplication of the parent process.
新線程很容易建立; 新流程須要複製父流程。
5.Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
線程能夠對同一進程的線程進行至關大的控制; 進程只能控制子進程。
6.Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.
對主線程的更改(取消,優先級更改等)可能會影響進程的其餘線程的行爲; 對父進程的更改不會影響子進程。
多線程指的是,在一個進程中開啓多個線程,簡單一點說:若是多個任務公用一塊地址空間,那必須在一個進程內開啓多個線程來完成多個任務(聯想:word的編輯,定時保存,預覽等)。
詳細的講分爲4點:
1.多線程共享一個進程的地址空間。
2.線程比進程更輕量級,線程比進程跟容易建立可撤銷,在不少操做系統中,建立一個線程比建立一個進程要快10-100倍,在有大量線程須要動態和快速修改時候,這一特性頗有用。
3.若多個線程都是cpu密集型,那麼並不能得到性能上的加強,可是若是存在大量的計算和大量的I/O處理,擁有多個線程運行這些活動彼此重疊運行,從而會加速程序的執行速度。
4.在多個cpu系統中,爲了最大限度的利用多核,能夠開啓多個線程,比開進程開銷小的多(這一條不太適用python)
例如:Notepad++,打開該程序後開啓了一個進程,可是該進程不止作一件事情,有監聽鍵盤輸入,文理文字,定時自動保存到硬盤等等操做,而這3個任務操做的都是同一快數據,於是不能用多進程。
只能在一個進程裏併發地開啓三個線程,若是是單線程,那就只能,鍵盤輸入的時候,不可以處理文字和自動保存,自動保存的時候又不能輸入和處理文字。
圖一
1.圖一可知:
不一樣進程之間是充滿敵意的,彼此搶佔,競爭cpu的關係,如360和qq搶佔資源。而同一進程是由一個程序員建立的,因此同一進程內的線程是合做關係,一個線程能夠訪問另一個線程內的內存地址,進 程的線程共享彼此的內存信息。
多個線程共享同一進程的地址空間中的資源,是對一臺計算機上多個進程的模擬,因此有時候也稱之爲輕量級的進程。
而一臺計算機上的多個進程,則共享物理內存,磁盤,打印機等其餘物理資源。
多線程的運行與多進程的運行相似,是cpu在多個線程之間的快速切換。
圖二
2.圖二可知:
相似進程,每一個線程內部也有本身的堆棧。
不一樣於進程,線程庫沒法利用時鐘中斷強制線程讓出CPU,能夠調用thread_yield運行線程自動放棄cpu,讓另一個線程運行。
3.總結:
線程一般是有益的,可是帶來了很多程序設計難度,線程的問題是:
1.父進程有多個線程,那麼開啓的子線程是否須要一樣多的線程。
若是是,那麼附近中的某個線程被阻塞,那麼copy到子進程後,copy版的線程也要被阻塞嗎?想想nginx的多線程模式接收用戶鏈接。
2.在同一個進程中,若是一個線程關閉了文件,而另一個線程準備往該文件內寫內容呢?
若是一個線程注意到沒有內存了,並開始分配更多的內存,在工做一半時,發生線程切換,新的線程也發現內存不夠,又開始分配更多的內存,這樣內存就被分配了不少次,這些問題都是多線程編程 的典型問題,須要仔細思考和設計的。
爲了實現可移植線程程序,IEEE在IEEE標準1003.1c中定義了線程標準,它定義的線程包叫Pthread。大部分Unix系統都支持該系統標準:
線程的實現能夠分爲2類:用戶級線程(User-Level Thread) 和內核級線程(Kernel-Level Thread),後者又稱之爲內核支持的線程或者輕量級線程。
在多線程操做系統中,各個系統的實現方式並不一樣,在有的 系統中實現了用戶級線程,有的系統中實現了內核級線程。
所以,在用戶空間模擬操做系統對進程的調度,來調用一個進程中的線程,每一個進程中都會有一個運行時的系統,用來調度線程。
此時當該進程後去cpu的時候,進程內再調度出一個線程去執行,同一時刻只有一個線程執行。
內核級線程:切換由內核控制,當線程進行切換的時候,由用戶態轉化爲內核態。
切換完畢要從內核態返回用戶態;
能夠很好的利用smp,即利用多核cpu。windows線程就是這樣的。
1.用戶級與內核級的線程區別:
2.內核線程的優缺點
優勢:
當有多個處理機制的時候,一個進程的多個線程能夠同時執行。
缺點:
由內核進行調度
3.用戶線程的優缺點
優勢:
1):線程的調度不須要內核直接參與,控制簡單
2):能夠在不支持線程的操做系統中實現
3):建立和銷燬線程,線程切換等線程管理的代價比內核線程少的的多
4):運行每一個進程控制本身的調度算法,線程管理比較靈活
5):線程可以利用的表空間和堆棧空間比內核級線程多
6):同一個進程中只能同時有一個線程在運行,若是一個線程使用了系統調用二阻塞,那麼整個進程都會被掛起。另外,頁面失效也會產生一樣的問題。
缺點:
資源調度按照進程進行,多個處理機制下,同一個進程中的線程只能在同一個處理機制下分時複用。
用戶級與內核級的多路複用,內核同一調度內核線程,每一個內核線程對應n個用戶線程。