# 多線成 多進程 同步 異步 協程 https://www.youtube.com/watch?v=olYdb0DdGtM 同一台電腦Process之間比起TCP協議來說 用webSake更減少效能 一台電腦 有核心 就能同時做多少 但每個要看他時間 幾GHz 代表他一秒能做多少事情 ## 对于操作系统而言进程、线程以及Goroutine协程的区别 https://www.yuque.com/aceld/golang/tdgbgf ## 基本介紹 * 同步:一個進程在執行某個請求的時候,若該請求需要一段時間才能返回信息,那麼這個進程將會一直等待下去,直到收到返回信息才繼續執行下去。 * 異步:進程不需要一直等下去,而是繼續執行下面的操作,不管其他進程的狀態。當有消息返回時系統會通知進程進行處理,這樣可以提高執行的效率。 * 進程:狹義上,就是正在運行的程序的實例。廣義上,進程是一個具有一定獨立功能的程序關於某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。 * 線程:線程是程序中一個單一的順序控制流程。進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分派CPU的基本單位。指運行中的程序的調度單位。 * 單線程:單線程在程序執行時,所走的程序路徑按照連續順序排下來,前面的必須處理好,後面的才會執行。單線程就是進程裡只有一個線程。 * 多線程:在單個程序中同時運行多個線程完成不同的工作,稱為多線程。 ## 線程 Thread 就是io 一組程序 或要發生的操作 線程會分配給核心 線程可以想像成存在於 process 裡面,而一個進程裡至少會有一個線程,前面有說 process 是 OS 分配資源的最小單位,而 thread 則是作業系統能夠進行運算排程的最小單位,也就是說實際執行任務的並不是進程,而是進程中的線程,一個進程有可能有多個線程,其中多個線程可以共用進程的系統資源,可以把進程比喻為一個工廠,線程則是工廠裡面的工人,負責任務的實際執行。 ## 併發原因 ![](https://i.imgur.com/KTowD29.png) 很多線成 core(內核)會切換 因為電腦這樣才有效率 ## 程式 Program 在了解進程與線程之前,得先談談 program 這個東西,其實所謂的 program 就是工程師撰寫的程式碼的集合,例如 Line、 Chrome 就個別是 program,而他們的特點是**還沒有被執行**,因此也就還沒有被載入至記憶體中,而是存放在`次級儲存裝`置中。 ## 進程 Process Process 進程則是指被執行且載入記憶體的 program。Process 也是 OS 分配資源的最小單位,可以從 OS 得到如 CPU Time、Memory…等資源,意思是這個 process 在運行時會消耗多少 CPU 與記憶體。文章一開始放了一張 MacOS 活動監視器的截圖,相信不管是使用哪種作業系統的讀者都有看過類似的介面,而監視器中列出的是你的電腦正在執行的應用程式,而它們其實就是一個個 process,可以從圖片中看出每一個 process 消耗的 CPU、CPU 時間與每個 process 的獨立 ID (PID)。 進程的優缺點與小結 優點:每個進程有自己獨立的系統資源分配空間,不同進程之間的資源不共享,因此不需要特別對進程做互斥存取的處理。 缺點:建立進程以及進程的上下文切換(Context Switch)都較消耗資源,進程間若有通訊的需求也較為複雜。 小結:程式 (Program)是寫好尚未執行的 code,程式被執行後才會變成進程 (Process)。 ## MultiProcessing 多進程 & MultiThreading 多線程 這兩個概念我想繼續利用工廠與工人的比喻會比較好理解與記憶。 Multiprocessing 好比建立許多工廠(通常會取 CPU 的數量),每個工廠中會分配ㄧ名員工(thread)執行工作,因此優勢在於同一時間內可以完成較多的事。 Multithreading 則是將許多員工聚集到同一個工廠內,它的優勢則是有機會讓相同的工作在比較短的時間內完成。 ## 多線程的 競爭危害(Race Condition) 剛剛有提到在多執行緒中 (Multithreading),不同 thread 是可以共享資源的,而若兩個 thread 若同時存取或改變全域變數,可能會發生同步 (Synchronization) 問題。若執行緒之間互搶資源,則可能產生死結 (Deadlock),因此使用多線程時必須特別注意避免這些狀況發生。 ## Concurrent & Parallel 並發與並行 ![](https://i.imgur.com/tUamX8k.png) 這兩個是許多人容易誤解的概念,然而透過上面的圖就可以一目瞭然,Parallel 並行是利用多個 CPU 達到同時並行處理任務的需求(也就是同一個時間點有許多任務在同時執行),Concurrent 則是許多任務在爭搶同一個 CPU 的資源,因此一個時間點只會有一個任務正在執行,只是因為切換非常快,使用者通常不會感覺到任務實際上一直在切換。 ## 協程 Coroutine 大部分的文章討論的都是 process 與 thread 的概念,直到最近在學 golang,碰到了 goroutine,才知道原來還有 coroutine 協程的存在 ![](https://i.imgur.com/HzbRwT7.png) 協程是一種使用者態的輕量級執行緒,協程的排程完全由使用者控制。 可以想像進程中有線程,而線程中則又有協程。而協程的調度完全由用戶控制,協程也會有自己的 registers、context、stack 等等,並且由協程的調度器來控制目前由哪個協程執行,哪個協程要被 block 。process 及 thread 的調度,是由 CPU 內核去進行調度,而協程卻不ㄧ樣,OS 甚至不知道協程的存在,如果 coroutine 被卡住,則會在用戶端直接切換另外一個 coroutine 給此 thread 繼續執行,這樣其他 coroutine 就不會被block住,讓資源能夠有效的被利用,藉此實現 Concurrent 的概念。 相較於建立一個線程需要花費 MB 等級的記憶體,建立一個協程可以壓到 KB 等級,協程間的切換也絕對快於線程間的切換 process: 台灣:程序、處理程序 對岸:進程 thread: 台灣:執行緒 對岸:線程 concurrent: 台灣:並行 大陸:並發 parallel: 台灣:平行 大陸:並行 ## 协程 协程的概念是相对多进程或者多线程来说的,他是一种协作式的**用户态线程** 1. 与之相对的,线程和进程是以**抢占式执行**的,意思就是系统帮我们自动快速切换线程和进程来让我们感觉同步运行的感觉,这个切换动作由系统自动完成协作式执行说的就是,想要切换线程,你必须要用户手动来切换 2. 协程为什么那么快原因就是因为,无需系统自动切换(系统自动切换会浪费很多的资源),而协程是我们用户手动切换,而且是在同一个栈上执行,速度就会非常快而且省资源。 但是,协程有他自己的问题:**协程只能有一个进程,一个线程在跑,一旦发生IO阻塞,这个程序就会卡住**。所以我们要使用协程之前,必须要保证我们所有的IO都必须是**非阻塞的**。 ## 所有IO非阻塞/异步IO IO无非就是几种 1. 读(硬盘的)的 2. 写(硬盘的)的 3. 网络请求(读和写) 所有的读和写,网络请求接口都要设置成非阻塞式的,当系统内核把这些玩意儿执行完毕以后,再通过回调函数,通知用户处理。在用户空间上来看,我们就一直保持在一个线程,一个进程之中,因此,这种速率极高! 为什么Nodejs并发量会那么变态的原因就是这一点:nodejs因为js线程只有一条(底层的IO使用多线程来实现非阻塞),为了让程序不会卡住,就一定要把所有的IO变成非阻塞异步,通过回调来告诉用户。 ###### tags: `觀念重點區`