個人分類: go
goroutine
runtime包中提供了幾個與goroutine相關的函式。gosched()讓當前正在執行的goroutine放棄cpu執行許可權。排程器安排其他正在等待的執行緒執行。
請看以下例子:
package main
import (
"runtime"
"fmt"
)func main()
func sayhello()
}func sayworld()
}
這種情況是單核的時候,如果是多核的話runtime.gomaxprocs(1),變成單核,多核的話,每次都不一樣,因為放棄cpu執行的許可權,另乙個cpu還是會繼續的。
從上面輸出結果可知,我們啟動了兩個執行緒,其中乙個執行緒輸出一句後呼叫gosched函式,釋放cpu許可權;之後另乙個執行緒獲得cpu許可權。這樣兩個執行緒交替獲得cpu許可權,才輸出了以上結果。
runtime.numcpu()返回了cpu核數,runtime.numgoroutine()返回當前程序的goroutine執行緒數。即便我們沒有開啟新的goroutine。
runtime.goexit()函式用於終止當前的goroutine,單defer函式將會繼續被呼叫。
package main
import (
"runtime"
"fmt"
)func test()()
for i := 0; i < 10; i++
}}func main()
var str string
fmt.scan(&str)
這兩句**是等待輸入的意思,在這裡用來阻止主線程關閉的。如果沒有這兩句的話,會發現我們的程式瞬間就結束了,而且什麼都沒有輸出。這是因為主線程關閉之後,所有開啟的goroutine都會強制關閉,他還沒有來得及輸出,就結束了。
但是這樣感覺怪怪的。如果有一種機制,在子執行緒結束的時候通知一下主線程,然後主線程再關閉,豈不是更好,這樣就不用無休止的等待了。於是就有了channel。
channel
goroutine之間通過channel來通訊,可以認為channel是乙個管道或者先進先出的佇列。你可以從乙個goroutine中向channel傳送資料,在另乙個goroutine中取出這個值。
使用make建立
var channel chan int = make(chan int)
// 或
channel := make(chan int)
生產者/消費者是最經典的使用示例。生產者goroutine負責將資料放入channel,消費者goroutine從channel中取出資料進行處理。
package main
import (
"fmt"
)func main()
func producer(c chan int)
}func consumer(c, f chan int)else}f
}
執行結果
可以將channel指定為單向通訊。比如
func producer(c chan
}func consumer(c }f
}channle可以是帶緩衝的。make的第二個引數作為緩衝長度來初始化乙個帶緩衝的channel:
c := make(chan int, 5)
向帶緩衝的channel傳送資料時,只有緩衝區滿時,傳送操作才會被阻塞。當緩衝區空時,接收才會阻塞。
可以通過以下程式調整傳送和接收的順序除錯
package main
import (
"fmt"
)func main()
select
如果有多個channel需要監聽,可以考慮用select,隨機處理乙個可用的channel
package main
import (
"fmt"
)func main()
quit
}()testmuti(c, quit)
}func testmuti(c, quit chan int)}}
channle超時機制
當乙個channel被read/write阻塞時,會被一直阻塞下去,直到channel關閉。產生乙個異常退出程式。channel內部沒有超時的定時器。但我們可以用select來實現channel的超時機制
package main
import (
"time"
"fmt"
)func main()
}
執行緒同步
假設現在我們有兩個執行緒,乙個執行緒寫檔案,乙個執行緒讀檔案。如果在讀檔案的同時,寫檔案的執行緒向檔案中寫資料,就會出現問題。為了保證能夠正確的讀寫檔案,在讀檔案的時候,不能進行寫入檔案的操作,在寫入時,不能進行讀的操作。這就需要互斥鎖。互斥鎖是執行緒間同步的一種機制,用了保證在同一時刻只用乙個執行緒訪問共享資源。go中的互斥鎖在sync包中。下面是個執行緒安全的map:
package main
import (
"errors"
"sync"
"fmt"
)func main()
go setvalue(m)
go m.display()
var str string
fmt.scan(&str)
}type mymap struct
func (this *mymap)get(key string)(int, error)
return i, nil
}func (this *mymap)set(key string, val int)
func (this *mymap)display()
}func setvalue(m *mymap)
}
執行結果 go之多執行緒
在go裡面,併發程式依靠的是goroutine和channel。goroutine可以理解為執行緒,當對乙個函式呼叫go,啟動乙個goroutine的時候,就相當於起來乙個執行緒來執行這個函式。比如 func getinfo name string,age int func main 輸出 star...
go語言多執行緒操作map
go語言裡的map因為是引用,所以多執行緒操作時必須加鎖.一開始我以為只要讀寫的key不會競爭就不會出現問題,但是測試後發現,即使寫的時候採用的是不同的key,也會發生多執行緒錯誤 fatal error concurrent map writes func main go func time.sl...
多執行緒 多執行緒原理
我們首先要知道什麼是多執行緒,說白了就是多個執行緒,執行緒是什麼呢,其實就是程序執行的途徑,那麼說道這裡我們又引入了乙個新的名字,就是程序,那麼我們來看看什麼是程序,其實我們自己也能看到,啟動電腦的任務管理器,我們就可以看到程序選項,裡面是我們電腦所有的程序,我們會發現有很多的程序.簡單地說就是程序...