Go語言學習筆記2/2
來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。chap04 並發編程
1.Go語言支援語言層級輕量層級線程,稱之為goroutine,由Go語言運行時runtime管理。如下多線程執行個體:
package main
import (
"fmt";
"sync";
"runtime"
)
var counter int = 0
func Count(lock *sync.Mutex){
lock.Lock()
counter++
fmt.Println(counter)
lock.Unlock()
}
func main(){
lock:=&sync.Mutex{}
for i:=0;i<10;i++ {
go Count(lock)
}
for {
lock.Lock()
c:=counter
lock.Unlock()
runtime.Gosched() //用於讓cpu讓出時間片
if c>=10 {
break
}
}
}
2.Go語言共用資料理念:不要通過共用記憶體來通訊,而應該通過通訊來共用記憶體。
3.channel是go語言goroutine間的通訊方式。可以使用channel在不同的goroutine線程之間傳遞訊息。channel是類型相關的。
定義:var chanName chan type ,初始化:chanName := make(chan type)。
寫入:chanName <- value,讀取:value := <- chanName。讀取都會導致程式阻塞等待。
package main
import "fmt"
import "time"
func Count(ch chan int){
ch <- 1
fmt.Println(time.Now().UnixNano())
}
func main(){
chs := make([]chan int,10)
for i:=0;i<10;i++{
chs[i] = make (chan int)
go Count(chs[i])
}
for _,ch := range(chs) {
<-ch
fmt.Println("--------")
}
}
輸出:
1470927062503429479
--------
4.select用於處理非同步io,類似於switch,但是case的條件必須是io操作,沒有判斷條件。select隨機執行一個可啟動並執行case。如果沒有case可運行,它將阻塞,直到有case可運行。
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case ch <- 0:
case ch <- 1:
}
i:=<-ch
fmt.Println("Value received",i)
}
}
需要確保執行時有一個case可以執行,否則死結:fatal error: all goroutines are asleep - deadlock!
package main
import "fmt"
func main(){
ch := make(chan int,1)
for {
select {
case <-ch :
}
fmt.Println("Value received")
}
}
5.緩衝機制:設定緩衝區,緩衝區寫滿後才阻塞寫。ch:=make(chan int,1024)
6.利用channel處理逾時:
package main
import "fmt"
import "time"
func main(){
timeout := make(chan bool,1)
go func(){
time.Sleep(time.Second)
timeout<-true
}()
var ch chan int
select {
case <- ch :
case <- timeout:
fmt.Println("TimeOut...")
}
}
7.單項channel:
正常:var ch chan int
單項寫:var ch chan<- int
單項讀:var ch <-chan int
8.runtime.GOMAXPROCS(N)設定N個cpu參與到運算。runtime.Sched()釋放時間片。
9.同步鎖:syncMutex。讀寫鎖:sync.RWMutex。
10.全域唯一操作:sync.Once
package main
import "fmt"
import "sync"
var once sync.Once
func hi() {
fmt.Print("hi")
}
func main(){
for i:=0;i<10;i++ {
fmt.Println("Round",i)
once.Do(hi)
}
}