(文章持續更新中...有志同道合的人能夠一塊兒探討下。整個系列(1~8)準備重寫,不過都是很基礎的入門筆記,想學到很深刻的東西則不建議閱讀...)bash
接口是雙方約定的一種合做協議。每一個接口類型由數個方法組成併發
type 接口類型名 interface{
方法名1( 參數列表1 ) 返回值列表1
方法名2( 參數列表2 ) 返回值列表2
…
}
type Writer interface {
Write(p []byte) (n int, err error)
}
複製代碼
Go 語言的源碼複用創建在包(package)基礎之上.Go 語言的入口 main() 函數所在的包(package)叫 main,main 包想要引用別的代碼,必須一樣以包的方式進行引用,Go 語言的包與文件夾一一對應,全部與包相關的操做,必須依賴於工做目錄(GOPATH)函數
GOPATH 絕對路徑提供項目的工做目錄ui
goroutine 的概念相似於線程,但 goroutine 由 Go 程序運行時的調度和管理。Go 程序會智能地將 goroutine 中的任務合理地分配給每一個 CPUspa
Go 程序中使用 go 關鍵字爲一個函數建立一個 goroutine。一個函數能夠被建立多個 goroutine,一個 goroutine 一定對應一個函數命令行
// 爲普通函數建立goroutine 的格式
go 函數名( 參數列表 )
複製代碼
若是須要在 goroutine 中返回數, 用通道(channel)把數據從 goroutine 中做爲返回值傳出線程
package main
import (
"fmt"
"time"
)
func running() {
var times int
for {
times++
fmt.Println("tick", times)
time.Sleep(time.Second)
}
}
func main() {
// 併發執行程序
go running()
// 接受命令行輸入, 不作任何事情
var input string
fmt.Scanln(&input)
}
複製代碼
通常狀況下,可使用 runtime.NumCPU() 查詢 CPU 數量,並使用 runtime.GOMAXPROCS() 函數進行設置指針
runtime.GOMAXPROCS(runtime.NumCPU())
複製代碼
併發和並行的概念code
併發:任務在不一樣的時間點在處理器進行處理。在同一時間點,任務並不會同時運行 並行:每個任務分配給每個處理器獨立完成。在同一時間點,任務必定是同時運行接口
Go語言通道
單純地將函數併發執行是沒有意義的。函數與函數間須要交換數據才能體現併發執行函數的意義
任什麼時候候,同時只能有一個 goroutine 訪問通道(channel Go語言中一種特殊類型)進行發送和獲取數據。(相似隊列,先進先出)
// 申明通道類型
var 通道變量 chan 通道類型(通道內的數據類型)
複製代碼
chan 類型的空值是 nil,聲明後須要配合 make 後才能使用
通道是引用類型,須要使用 make 進行建立
通道實例 := make(chan 數據類型)
ch1 := make(chan int) // 建立一個整型類型的通道
ch2 := make(chan interface{}) // 建立一個空接口類型的通道, 能夠存聽任意格式
type Equip struct{ /* 一些字段 */ }
ch2 := make(chan *Equip) // 建立Equip指針類型的通道, 能夠存放*Equip
複製代碼
通道建立後,就可使用通道進行發送和接收操做
通道的發送使用特殊的操做符<-
// 數據經過通道發送數據格式
通道變量 <- 值(值的類型必須與ch通道的元素類型一致)
// 建立一個空接口通道
ch := make(chan interface{})
// 將0放入通道中
ch <- 0
// 將hello字符串放入通道中
ch <- "hello"
複製代碼
發送將持續阻塞直到數據被接收
把數據往通道中發送時,若是接收方一直都沒有接收,那麼發送操做將持續阻塞。Go 程序運行時能智能地發現一些永遠沒法發送成功的語句並作出提示,代碼以下:
package main
func main() {
// 建立一個整型通道
ch := make(chan int)
// 嘗試將0經過通道發送
ch <- 0
}
複製代碼
通道接收一樣使用<-操做符
通道的收發操做在不一樣的兩個 goroutine 間進行
接收將持續阻塞直到發送方發送數據
通道一次只能接收一個數據元素
阻塞模式接收數據時,將接收變量做爲<-操做符的左值,執行該語句時將會阻塞,直到接收到數據並賦值給 data 變量
// 阻塞式接收值
data := <-ch
// 非阻塞式
data, ok := <-ch
data 表示接收到的數據
ok 表示是否接收到數據
非阻塞的通道接收方法可能形成高的 CPU 佔用,所以使用很是少
// 忽略從通道返回的數據
<-ch
複製代碼
Go 的通道能夠在聲明時約束其操做方向,如只發送或是隻接收。這種被約束方向的通道被稱作單向通道
只能發送的通道類型爲chan<-,只能接收的通道類型爲<-chan
var 通道實例(聲明的通道變量) chan<- 元素類型 // 只能發送
var 通道實例(聲明的通道變量) <-chan 元素類型 // 只能接收
複製代碼
使用 close() 來關閉一個通道.給被關閉通道發送數據將會觸發panic
close(ch)
複製代碼
互斥鎖是一種經常使用的控制共享資源訪問的方法,它可以保證同時只有一個 goroutine 能夠訪問共享資源
Lock()
UnLock()