直到20世紀50年代中期,還沒出現操做系統,計算機工做採用手工操做方式。程序員將對應於程序和數據的已穿孔未的紙帶(或卡片)裝入輸入機,而後啓動輸入機把程序和數據輸入計算機內存,接着經過控制檯開關啓動程序針對數據運行;計算完畢,打印機輸出計算結果;用戶取走結果並卸下紙帶(或卡片)後,才讓下一個用戶上機。linux
手工操做方式的兩個特色:程序員
(1)用戶獨佔全機。不會出現因資源已被其餘用戶佔用而等待的現象,但資源的利用率低。面試
(2)CPU等待手工操做。CPU的利用不充分。算法
20世紀50年代後期,出現人機矛盾:手工操做的慢速度和計算機的高速度之間造成了尖銳矛盾,手工操做方式已嚴重損害了系統資源的利用率(使資源利用率降爲百分之幾,甚至更低),不能容忍。惟一的解決辦法:只有擺脫人的手工操做,實現做業的自動過渡。這樣就出現了成批處理。編程
批處理系統的追求目標是提升系統資源利用率和系統吞吐量,以及做業流程的自動化。批處理系統的一個重要缺點是不提供人機交互能力,給用戶使用計算機帶來不便。安全
批處理是指用戶將一批做業提交給操做系統後就再也不干預,由操做系統控制它們自動運行。這種採用批量處理做業技術的操做系統稱爲批處理操做系統。批處理操做系統分爲單道批處理系統和多道批處理系統。批處理操做系統不具備交互性,它是爲了提升CPU的利用率而提出的一種操做系統。服務器
早期的批處理系統屬於單道批處理系統,其目的是減小做業間轉換時的人工操做,從而減小CPU的等待時間。它的特徵是內存中只容許存放一個做業,即當前正在運行的做業才能駐留內存,做業的執行順序是先進先出,即按順序執行。網絡
因爲在單道批處理系統中,一個做業單獨進入內存並獨佔系統資源,直到運行結束後下一個做業才能進入內存,看成業進行I/O操做時,CPU只能處於等待狀態,所以,CPU利用率較低,尤爲是對於I/O操做時間較長的做業。爲了提升CPU的利用率,在單道批處理系統的基礎上引入了多道程序設計技術,這就造成了多道批處理系統,即在內存中可同時存在若干道做業,做業執行的次序與進入內存的次序無嚴格的對應關係,由於這些做業是經過必定的做業調度算法來使用CPU的,一個做業在等待I/O處理時,CPU調度另一個做業運行,所以CPU的利用率顯著地提升了。數據結構
批處理系統中,一個做業能夠長時間地佔用CPU。而分時系統中,一個做業只能在一個時間片的時間內使用CPU。批處理系統不是嚴格意義上的操做系統。
多道程序技術(Multiprogramming)運行的特徵:多道、宏觀上並行、微觀上串行。多道程序技術的提出是爲了改善CPU的利用率。它須要硬件支持,並令CPU調度其餘硬件工做。
(1)多道:計算機內存中同時存放幾道相互獨立的程序(一開始稱爲做業,後來演化爲進程);
(2)宏觀上並行:同時進入系統的幾道程序都處於運行過程當中,即它們前後開始了各自的運行,但都未運行完畢;
(3)微觀上串行:實際上,各道程序輪流地用CPU,並交替運行。
所謂多道程序設計指的是容許多個程序同時進入一個計算機系統的主存儲器並啓動進行計算的方法。也就是說,計算機內存中能夠同時存放多道(兩個以上相互獨立的)程序,它們都處於開始和結束之間。從宏觀上看是並行的,多道程序都處於運行中,而且都沒有運行結束;從微觀上看是串行的,各道程序輪流使用CPU,交替執行。引入多道程序設計技術的根本目的是爲了提升CPU的利用率,充分發揮計算機系統部件的並行性。現代計算機系統都採用了多道程序設計技術。
例如,若是一個進程有20%的時間使用CPU進行計算,另外80%的時間用來進行I/O,則在單道編程下CPU的利用率只有20%,由於在I/O時間,CPU沒有事情作(只有一個進程)。
若是是支持兩個進程的操做系統,即便用2道編程,則CPU只在兩個進程同時進行I/O時纔會處於閒置狀態,所以CPU利用率將會提升到:1-0.8*0.8=0.36=>36%。同理,若是同時運行更多的進程,CPU利用率會逐步提升,直到某個臨界點爲止。(PS:這裏的例子忽略了進程切換所須要的系統消耗)
雖然用戶獨佔全機資源,而且直接控制程序的運行,能夠隨時瞭解程序運行狀況,但這種工做方式因獨佔全機形成資源效率極低。因而一種新的追求目標出現了:既能保證計算機效率,又能方便用戶使用計算機。20世紀60年代中期,計算機技術和軟件技術的發展使這種追求成爲可能。
分時操做系統是使一臺計算機採用時間片輪轉的方式同時爲幾個、幾十個甚至幾百個用戶服務的一種操做系統。
把計算機與許多終端用戶鏈接起來,分時操做系統將系統處理機時間與內存空間按必定的時間間隔,輪流地切換給各終端用戶的程序使用。因爲時間間隔很短,每一個用戶的感受就像他獨佔計算機同樣。分時操做系統的特色是可有效增長資源的使用率。
分時系統是當今計算機操做系統中最廣泛使用的一類操做系統。實現多任務處理的方式有搶佔式(Preemption)與協做式。協做式環境下,下一個進程被調度的前提是當前進程主動放棄時間片;搶佔式環境下,操做系統徹底決定進程調度方案,操做系統能夠剝奪耗時長的進程的時間片,提供給其它進程。
每一個程序最終都會加載到內存中運行。多道程序設計的出現提供了進程的雛形 – 系統內部能夠存放多於一個做業。分時操做系統中,系統內部也能夠同時存在超過一個程序,這些同時存在於計算機內存中的程序就被稱爲進程。但當咱們在一個現代系統上運行一個程序時,會獲得一個假象,就好像咱們的程序是系統中當前運行着的惟一的程序。
進程的實現:經過操做系統的內存分配和調度。OS經過進程控制塊管理進程。經過虛擬內存實現進程隔離,一個進程沒法訪問其餘進程正在佔有的資源。但不安全的操做系統例如DOS,任何進程均可以訪問其餘進程的資源。
進程讓每一個用戶感受本身在獨佔CPU。
進程是多道編程天然而然的產物,而多道編程的目的則是爲了提升計算機CPU的利用率(或者說系統的吞吐量)。
(1)物理視角:從物理內存的分配來看,每一個進程佔用一片內存空間,從這點上看,進程其實就是內存的某片空間。因爲在任意時刻,一個CPU只能執行一條指令,所以任意時刻在CPU上執行的進程只有一個,而到底執行哪條指令是由物理程序計數器指定。所以,在物理層面,全部進程共用一個程序計數器,只是CPU在不停地作進程切換。
(2)邏輯視角:從邏輯層面來看,每一個進程均可以執行,也能夠暫時掛起讓別的進程執行,以後又能夠接着執行。因此,進程須要想辦法保持狀態才能在下次接着執行時從正確的地點(即上下文)開始。所以,每一個進程都有本身的計數器,記錄其下一條指令所在的位置。(從邏輯上來講,程序計數器能夠有多個)
(3)時序視角:從時間來看,每一個進程都必須往前推動。在運行必定時間後,進程都應該完成了必定的工做量。換句話說,每次進程返回,它都處在上次返回點以後。
在現代操做系統中,進程管理和調度是操做系統的功能之一,特別是多任務處理的情況下,這是必要的功能。操做系統將資源分配給各個進程,讓進程間能夠分享與交換信息,保護每一個進程擁有的資源,不會被其餘進程搶走,以及使進程間可以同步(必要的話)。爲了達到這些要求,操做系統爲每一個進程分配了一個數據結構,用來描述進程的狀態,以及進程擁有的資源。操做系統能夠經過這個數據結構,來控制每一個進程的運做。
(1)物理基礎:進程的物理基礎是程序,程序又運行在計算機上,所以計算機上要運行程序首先要解決進程的存儲:給進程分配內存,使其安身立命。因爲多個進程可能同時並存,所以須要考慮如何讓多個進程共享同一個物理內存而不發生衝突。OS經過內存管理(虛擬內存和進程隔離)來解決這個問題。
(2)進程切換:進程運行其實是指進程在CPU上執行,那麼如何將CPU在多個進程之間進行切換也是一個問題。OS經過進程調度來解決這個問題。所謂進程調度,就是決定在何時讓什麼進程來使用CPU,並在調度切換進程時,不會損失以前工做的數據。
虛擬內存是計算機系統內存管理的一種技術。它使得應用程序認爲它擁有連續的可用的內存(一個連續完整的地址空間),而實際上,它一般是被分隔成多個物理內存碎片,還有部分暫時存儲在外部磁盤存儲器上,在須要時進行數據交換。目前,大多數操做系統都使用了虛擬內存,如Windows家族的「虛擬內存」;Linux的「交換空間」等。
電腦中所運行的程序均需經由內存執行,若執行的程序佔用內存很大或不少,則會致使內存消耗殆盡。當內存耗盡時,Windows會用虛擬存儲器進行補償,它將計算機的RAM和硬盤上的臨時空間組合。當RAM運行速率緩慢時,它便將數據從RAM移動到稱爲「分頁文件」的空間中。將數據移入分頁文件可釋放RAM,以便完成工做。通常而言,計算機的RAM容量越大,程序運行得越快。若計算機的速率因爲RAM可用空間匱乏而減緩,則可嘗試經過增長虛擬內存來進行補償。可是,計算機從RAM讀取數據的速率要比從硬盤讀取數據的速率快,於是擴增RAM容量(可加內存條)是最佳選擇。
虛擬內存是Windows做爲內存使用的一部分硬盤空間,在硬盤上其實就是一個碩大無比的文件,文件名是PageFile.sys,一般狀態下是看不到的。必須關閉資源管理器對系統文件的保護功能才能看到這個文件。虛擬內存有時候也被稱爲是「頁面文件」就是從這個文件的文件名中來的。
進程隔離是爲保護操做系統中進程互不干擾而設計的一組不一樣硬件和軟件的技術。這個技術是爲了不進程A寫入進程B的狀況發生。進程的隔離實現使用了虛擬內存。進程A的虛擬地址和進程B的虛擬地址不一樣,這樣就防止進程A將數據信息寫入進程B。
進程隔離的安全性經過禁止進程間內存的訪問能夠方便實現。相比之下,一些不安全的操做系統(例如DOS)可以容許任何進程對其餘進程的內存進行寫操做。
在多進程的環境裏,雖然從概念上看,有多個進程在同時執行,但在單個CPU下,在任什麼時候刻只能有一個進程處於執行狀態,而其餘進程則處於非執行狀態。那麼問題來了,咱們是如何肯定在任意時刻到底由哪一個進程執行,哪些不執行呢?這就涉及到進程管理的一個重要組成部分:進程調度。
進程調度是操做系統進程管理的一個重要組成部分,其任務是選擇下一個要運行的進程。發生時鐘中斷是激發調度的其中一個可能。當調度結束,選擇下一個要運行的進程以後,若是選擇的進程不是如今正在運行的進程,CPU要進行上下文交換(Context Switching)。
咱們必須解決以下問題:
通常的程序任務分爲三種:CPU計算密集型、IO密集型與平衡(計算與IO各半)型,對於不一樣類型的程序,調度須要達到的目的也有所不一樣。對於IO密集型,響應時間最重要;對於CPU密集型,則週轉時間最重要;而對於平衡型,進行某種響應和週轉之間的平衡就顯得比較重要。所以,進程調度的目標就是要達到極小化平均響應時間、極大化系統吞吐率、保持系統各個功能部件均處於繁忙狀態和提供某種貌似公平的機制。
先來先服務(FCFS)算法是一種最多見的算法,它是人的本性中的一種公平觀念。其優勢就是簡單且實現容易,缺點則是短的工做有可能變得很慢,由於其前面有很長的工做在執行,這樣就會形成用戶的交互式體驗也比較差。例如排隊辦理業務時,你要辦理的業務只須要幾分鐘就能夠辦好,可是你前面的一我的辦理的事情很複雜須要1個小時,這時你須要在他後面等好久,因而你就想到:要是每一個人輪流辦理10分鐘事務的話,那該多好!因而就出現了時間片輪轉算法。
時間片輪轉是對FCFS算法的一種改進,其主要目的是改善短程序的響應時間,實現方式就是週期性地進行進程切換。時間片輪轉的重點在於時間片的選擇,須要考慮多方因素:若是運行的進程多時,時間片就須要短一些;進程數量少時,時間片就能夠適當長一些。所以,時間片的選擇是一個綜合的考慮,權衡各方利益,進行適當折中。
可是,時間片輪轉的系統響應時間也不必定老是比FCFS的響應時間短。時間片輪轉是一種大鍋飯的作法,可是現實生活中倒是走的「一部分人先富,先富帶動後富」的路線。例如,若是有30個任務,其中一個任務只須要1秒時間執行,而其餘29個任務須要30秒鐘執行,若是由於某種緣由,這個只要1秒鐘的任務排在另外29個任務的後面輪轉,則它須要等待29秒鐘才能執行(假定時間片爲1秒)。因而,這個任務的響應時間和交互體驗就變得很是差。所以,短任務優先算法被提出。
短任務優先算法的核心是全部的任務並不都同樣,而是有優先級的區分。具體來講,就是短任務的優先級比長任務的高,而咱們老是安排優先級高的任務先運行(這可能會致使飢餓)。
短任務優先算法又分爲兩種類型:一種是非搶佔式,一種是搶佔式。非搶佔式當已經在CPU上運行的任務結束或阻塞時,從候選任務中選擇執行時間最短的進程來執行。而搶佔式則是每增長一個新的進程就須要對全部進程(包括正在CPU上運行的進程)進行檢查,誰的時間短就運行誰。
因爲短任務優先老是運行須要執行時間最短的程序,所以其系統平均響應時間在以上幾種算法中是最優的,這也是短任務優先算法的優勢。但短任務優先算法也有缺點:一是可能形成長任務永遠沒法獲得CPU時間從而致使「飢餓」。二是如何知道每一個進程還須要運轉多久?因而爲了解決第一個缺點,優先級調度算法被提出。而第二個缺點則能夠採起一些啓發式的方法來進行估算,目前不少的人工智能算法均可以作這個事。
優先級調度算法給每一個進程賦予一個優先級,每次須要進程切換時,找一個優先級最高的進程進行調度。這樣若是賦予長進程一個高優先級,則該進程就不會再「飢餓」。事實上,短任務優先算法自己就是一種優先級調度,只不過它給予短進程更高的優先級而已。
該算法的優勢在於能夠賦予重要的進程以高優先級以確保重要任務可以獲得CPU時間,其缺點則有二:一是低優先級的進程可能會「飢餓」,二是響應時間沒法保證。第一個缺點能夠經過動態地調節任務的優先級解決,例如一個進程若是等待時間過長,其優先級將持續提高,超越其餘進程的優先級,從而獲得CPU時間。第二個缺點能夠經過將一個進程優先級設置爲最高來解決,但即便將優先級設置爲最高,但若是每一個人都將本身的進程優先級設置爲最高,其響應時間仍是沒法保證。
以前的算法都存在必定缺點,那麼能否有一個算法混合他們的優勢,摒棄它們的缺點,這就是所謂的混合調度算法。混合調度算法將全部進程分爲不一樣的大類,每一個大類爲一個優先級。若是兩個進程處於不一樣的大類,則處於高優先級大類的進程優先執行;若是處於同一個大類,採用時間片輪轉算法來執行。
當發生上下文切換時,進程和CPU互動的資料(存儲在CPU的寄存器中)須要保存。由於這些資料很快就會被另外一個進程覆蓋(經過和CPU的互動)。這些資料通常以名爲進程控制塊(Process Control Block,PCB)的數據結構儲存起來。通常來講,這些資料應該包含:寄存器、程序計數器、狀態字、棧指針、優先級、進程ID、建立時間、所耗CPU時間、當前持有的各類句柄等等。
進程本身的資料是不須要保存的,由於它儲存在內存中一塊固定的空間,並且進程隔離已經保證了這些資料是安全的。當進程恢復運行時,它只須要再次回到屬於它的空間就能夠找到上次全部的資料。
簡單的說,上下文切換就是當進程調度致使要切換進程時,當前運行的進程將資料儲存進進程控制塊,而後經過調度算法選擇下一個進程,被選中的(當前在睡眠)的進程從進程控制塊中得到本身以前工做的信息,而後從新開始工做的過程。
在三種狀況下可能會發生上下文切換:中斷處理,多任務處理,用戶態切換。在中斷處理中,其餘程序的行爲打斷了當前正在運行的程序。當CPU接收到中斷請求時,會在正在運行的程序和發起中斷請求的程序之間進行一次上下文切換。在多任務處理中,CPU會在不一樣程序之間來回切換,每一個程序都有相應的處理時間片,CPU在兩個時間片的間隔中進行上下文切換。用戶態切換則是用戶本身的行爲,例如從遊戲中切出來,看一會網站的行爲。
上下文切換一般是計算密集型的。也就是說,它須要至關可觀的處理器時間,會對性能形成負面影響。類似的,線程也存在上下文切換。
進程間通訊(IPC,Inter-Process Communication),指至少兩個進程或線程間傳送數據或信號的一些技術或方法。每一個進程都有本身的一部分獨立的系統資源,彼此是隔離的。爲了能使不一樣的進程互相訪問資源並進行協調工做,纔有了進程間通訊。舉一個典型的例子,使用進程間通訊的兩個應用能夠被分類爲客戶端和服務器,客戶端進程請求數據,服務端回覆客戶端的數據請求。有一些應用自己既是服務器又是客戶端,這在分佈式計算中,時常能夠見到。這些進程能夠運行在同一計算機上或網絡鏈接的不一樣計算機上。
在類Unix操做系統(以及一些擴展例如Windows)中,管道(Pipeline)是原始的軟件管道:便是一個由標準輸入輸出連接起來的進程集合,因此每個進程的輸出(stdout)被直接做爲下一個進程的輸入(stdin)。管道所佔的空間既能夠是內存也能夠是磁盤。
要建立一個管道,一個進程只須要調用管道建立的系統調用(系統API)便可,該系統調用所作的事情就是在某種存儲介質上劃出一片空間,賦給其中一個進程寫的權利,另外一個進程讀的權利。
C#中相似的通訊機制能夠參考此文:http://www.cnblogs.com/yukaizhao/archive/2011/08/04/system-io-pipes.html
套接字(Socket)的功能很是強大,能夠支持不一樣層面、不一樣應用、跨網絡的通訊。使用套接字進行通訊須要雙方均建立一個套接字,其中一方做爲服務器方,另一方做爲客戶方。服務器方必須首先建立一個服務區套接字,而後在該套接字上進行監聽,等待遠方的鏈接請求。客戶方也要建立一個套接字,而後向服務器方發送鏈接請求。服務器套接字在受到鏈接請求以後,將在服務器方機器上新建一個客戶套接字,與遠方的客戶方套接字造成點到點的通訊通道。以後,客戶方和服務器方即可以直接經過相似於send和recv的命令在這個建立的套接字管道上進行交流了。
信號相似於咱們生活中的電報,若是你想給某人發一封電報,就擬好電文,而後將電文和收報人的信息都交給電報公司。電報公司則將電報發送到收報人所在地的郵局,並通知收報人來取電報。其中,發報文時無需收報人事先知道,也無需進行任何協調。若是對方選擇不對信號作出響應,則將被OS終止運行。
在計算機中,信號就是一個內核對象或者是一個內核數據結構。發送方將該數據結構的內容填好,並指明該信號的目標進程後,發出特定的軟件中斷(這就是一個發電報的操做)。OS接收到特定的中斷請求後,知道是有進程要發送信號,因而到特定的內核數據結構裏查找信號接收方,並進行通知。接到通知的進程則對信號進行相應處理。
信號量來源於鐵路的運行:在一條單軌鐵路上,任什麼時候候只容許有一列火車行駛在該鐵路上,而管理這條鐵路的系統就是信號量。任何一列火車必須等到代表該鐵路能夠行駛的信號後才能進入軌道。當列車進入後,須要將信號改成禁止狀態進入來防止別的列車同時進入。而當列車駛出單軌後,則須要將信號變回容許進入狀態,這很像之前的旗語。固然,經過聯想到咱們實際開發中常常用的鎖,這就更容易理解了。
在計算機中,信號量實際上就是一個簡單整數。一個進程在信號變爲0或1的狀況下推動,並將信號變爲1或0來防止別的進程同時推動。當該進程完成任務後,則將信號再改成0或1,從而容許其餘進程執行。從而咱們也能夠看出,信號量已經不僅是一種通訊機制,更是一種同步機制。
在系統中,給予每個進程一個信號量,表明每一個進程目前的狀態,未獲得控制權的進程會在特定地方被強迫停下來,等待能夠繼續進行的信號到來。若是信號量是一個任意的整數,一般被稱爲計數信號量(Counting semaphore),或通常信號量(general semaphore);若是信號量只有二進制的0或1,稱爲二進制信號量(binary semaphore)。在linux系中,二進制信號量(binary semaphore)又稱Mutex。
計數信號量具有兩種操做動做,以前稱爲V(又稱signal())與P(wait())。V操做會增長信號量S的數值,P操做會減小它。
運做方式:
C#對信號量的實現是Mutex和Semaphore。
兩個進程共同擁有同一片內存。對於這片內存中的任何內容,兩者都可以訪問。要使用共享內存進行通訊,進程A首先須要建立一片內存空間做爲通訊用,而其餘進程B則將這片內存映射到本身的(虛擬)地址空間。這樣,進程A讀寫本身地址空間中對應共享內存的區域時,就是在和進程B進行通訊。
消息隊列是一列具備頭和尾的消息排列,新來的消息放在隊列尾部,而讀取消息則從隊列頭部開始。
這樣看來,它和管道十分相似,一頭讀,一頭寫?的確,看起來很像管道,但又不是管道:
(1)消息隊列無固定的讀寫進程,任何進程均可以讀寫;而管道須要指定誰讀和誰寫;
(2)消息隊列能夠同時支持多個進程,多個進程能夠讀寫消息隊列;即所謂的多對多,而管道是點對點;
(3)消息隊列只在內存中實現,而管道還能夠在磁盤上實現;
線程是CPU的一個虛擬。
微軟決定在一個進程中運行應用程序的每一個實例。進程是應用程序要使用的資源的一個集合。當程序在進程中開始運行時,它就如同被關進了一個密閉的空間,裏面有全部它須要的東西。不一樣的密閉空間不會發生關係,任何一個進程死掉不會致使整個系統崩潰。進程有本身的虛擬地址空間,確保這個進程使用的代碼不會被其餘進程訪問。而且當進程失去響應時,系統仍然能夠工做,還能夠用其餘進程殺死失去響應的進程。
聽起來彷佛沒問題?但雖然應用程序與操做系統之間已經透過進程來達到隔離和保護的效果,但是它們仍然有共享的資源:CPU。若是機器只有一個CPU,那麼當某個應用程序進入無窮循環,那個惟一的CPU就會忙着跑無窮循環而無暇照顧其餘應用程序,形同鎖住。因而,用戶會發現每一個應用程序都沒法響應了,不管鼠標點在哪裏都不起做用。爲了解決這個CPU沒法分身的問題,線程(thread)便應運而生。
Windows經過線程來虛擬化CPU。線程使得每一個進程(至少擁有一個線程)擁有CPU的一個「分身」(稱爲邏輯CPU,真正的CPU稱爲物理CPU)。當一個線程進入無限循環時,其餘線程仍然能夠繼續運行。
線程的好處以下:
1. 在不少現代的大型程序(例如Word)中,一個程序同時在作不少事情。當咱們使用Microsoft Word時,其實是打開了多個線程。這些線程一個負責顯示,一個負責接收輸入,一個定時進行存盤。這些線程一塊兒運轉,讓咱們感受到輸入和顯示同時發生,而不用鍵入一些字符等待一下子才顯示到屏幕上。在不經意間,Word還能按期自動保存。這須要多個線程互相同步或互斥的並行完成工做,而將這些工做分解到不一樣的線程中去無疑簡化了編程模型。
2. 由於線程相比進程來講更加輕量,因此線程的建立和銷燬的代價更小。
3. 線程提升了性能,雖然線程宏觀上是並行的,但微觀上倒是串行(經過時間片)。從CPU角度線程沒法提高性能,但若是某些線程涉及到等待資源(好比IO,等待輸入)時,多線程容許進程中的其它線程繼續執行而不是整個進程被阻塞,所以提升了CPU的利用率,從這個角度會提高性能(和多道程序設計相同)。
4. 在多CPU或多核的狀況下,使用線程不只僅在宏觀上並行,在微觀上也是並行的。
在線程模式下,一個進程至少有一個線程,也能夠有多個線程。線程和進程既有類似又有不一樣之處。
類似:
不一樣之處:
同進程同樣,線程也須要調度,通訊和同步。
http://www.cnblogs.com/edisonchou/p/5022508.html
https://zh.wikipedia.org/wiki/%E8%A1%8C%E7%A8%8B%E9%96%93%E9%80%9A%E8%A8%8A
http://www.cnblogs.com/edisonchou/p/5037403.html
http://www.cnblogs.com/CareySon/archive/2012/05/04/ProcessAndThread.html
百度百科