### 進程和線程介紹

### 程序、進程和線程的關系示意圖

### 并發和并行
1) 多線程程序在單核上運行,就是并發
2) 多線程程序在多核上運行,就是并行
3) 示意圖:


### **Go 協程和 Go 主線程**
Go 主線程(有程序員直接稱為線程/也可以理解成進程): 一個 Go 線程上,可以起多個協程,你可以這樣理解,協程是輕量級的線程\[編譯器做優化\]。
Go 協程的特點
1) 有獨立的棧空間
2) 共享程序堆空間
3) 調度由用戶控制
4) 協程是輕量級的線程

### **goroutine-快速入門**
1) 在主線程(可以理解成進程)中,開啟一個 goroutine, 該協程每隔 1 秒輸出 "hello,world"
2) 在主線程中也每隔一秒輸出"hello,golang", 輸出 10 次后,退出程序
3) 要求主線程和 goroutine 同時執行.
4) 畫出主線程和協程執行流程圖


1) 主線程是一個物理線程,直接作用在 cpu 上的。是重量級的,非常耗費 cpu 資源。
2) 協程從主線程開啟的,是輕量級的線程,是邏輯態。對資源消耗相對小。
3) Golang 的協程機制是重要的特點,可以輕松的開啟上萬個協程。其它編程語言的并發機制是一
般基于線程的,開啟過多的線程,資源耗費大,這里就突顯 Golang 在并發上的優勢了
### **goroutine 的調度模型**



### **設置 Golang 運行的 cpu 數**
為了充分了利用多 cpu 的優勢,在 Golang 程序中,設置運行的 cpu 數目

## **channel(管道)-看個需求**
需求:現在要計算1-200的各個數的階乘,并且把各個數的階乘放入到map中。最后顯示出來。要求使用goroutine完成




## **不同 goroutine 之間如何通訊**
1)全局變量的互斥鎖
2)使用管道channel來解決
## **使用全局變量加鎖同步改進程序**
因為沒有對全局變量m加鎖,因此會出現資源爭奪問題,代碼會出現錯誤,提示concurrent map writes
解決方案:加入互斥鎖 ?我們的數的階乘很大,結果會越界,可以將求階乘改成sum+=uint64(i)
代碼改進


#### **為什么需要channel**
1)前面使用全局變量加鎖同步來解決goroutine的通訊,但不完美 2)主線程在等待所有goroutine全部完成的時間很難確定,我們這里設置10秒,僅僅是估算。 3)如果主線程休眠時間長了,會加長等待時間,如果等待時間短了,可能還有goroutine處于工作
狀態,這時也會隨主線程的退出而銷毀
4)通過全局變量加鎖同步來實現通訊,也并不利用多個協程對全局變量的讀寫操作。
5)上面種種分析都在呼喚一個新的通訊機制\-channel