Go语言goroutine+channel+select简介
goroutine:
Go語(yǔ)言是原生支持語(yǔ)言級(jí)并發(fā)的,這個(gè)并發(fā)的最小邏輯單元就是goroutine。goroutine就是Go語(yǔ)言提供的一種用戶(hù)態(tài)線程,這種用戶(hù)態(tài)線程是跑在內(nèi)核級(jí)線程之上的,goroutine在運(yùn)行時(shí)的調(diào)度是由Go語(yǔ)言提供的調(diào)度器來(lái)進(jìn)行的,創(chuàng)建一個(gè)goroutine使用關(guān)鍵字go,go創(chuàng)建的goroutine不會(huì)阻塞主線程:
go func_name()
Go程序中沒(méi)有語(yǔ)言級(jí)的關(guān)鍵字讓你去創(chuàng)建一個(gè)內(nèi)核線程,你只能創(chuàng)建goroutine,內(nèi)核線程只能由調(diào)度器根據(jù)實(shí)際情況去創(chuàng)建。
調(diào)度器原理參考鏈接:http://studygolang.com/articles/1855
?
channel:
Channel是Go中的一個(gè)核心類(lèi)型,可以把它看成一個(gè)管道,通過(guò)它可以發(fā)送或者接收數(shù)據(jù)進(jìn)行通訊(communication)。配合goroutine,就形成了一種既簡(jiǎn)單又強(qiáng)大的請(qǐng)求處理模型,即N個(gè)工作goroutine將處理的中間結(jié)果或者最終結(jié)果放入一個(gè)channel,另外有M個(gè)工作goroutine從這個(gè)channel拿數(shù)據(jù),再進(jìn)行進(jìn)一步加工,通過(guò)組合這種過(guò)程,可以勝任各種復(fù)雜的業(yè)務(wù)模型。
channel的基本操作:
var c chan int???//聲明一個(gè)int類(lèi)型的channel,注意,該語(yǔ)句僅聲明,不初始化channel
c := make(chan type_name)???//創(chuàng)建一個(gè)無(wú)緩沖的type_name型的channel,無(wú)緩沖的channel當(dāng)放入1個(gè)元素后,后續(xù)的輸入便會(huì)阻塞
c := make(chan type_name, 100)???//創(chuàng)建一個(gè)緩沖區(qū)大小為100的type_name型的channel
c <- x???//將x發(fā)送到channel c中,如果channel緩沖區(qū)滿,則阻塞當(dāng)前goroutine
<- c???//從channel c中接收一個(gè)值,如果緩沖區(qū)為空,則阻塞
x = <- c???//從channel c中接收一個(gè)值并存到x中,如果緩沖區(qū)為空,則阻塞
x, ok = <- c???//從channel c中接收一個(gè)值,如果channel關(guān)閉了,那么ok為false(在沒(méi)有defaultselect語(yǔ)句的前提下),在channel未關(guān)閉且為空的情況下,仍然阻塞
close(c)???//關(guān)閉channel c
for term := range c {}???//等待并取出channelc中的值,直到channel關(guān)閉,會(huì)阻塞
單向channel:
var ch1 chan<- float64????//只能向里面寫(xiě)入float64的數(shù)據(jù),不能讀取
var ch2 <-chan int????????//只能讀取int型數(shù)據(jù)
?
select:
select用于在多個(gè)channel上同時(shí)進(jìn)行偵聽(tīng)并收發(fā)消息,當(dāng)任何一個(gè)case滿足條件時(shí)即執(zhí)行,如果沒(méi)有可執(zhí)行的case則會(huì)執(zhí)行default的case,如果沒(méi)有指定defaultcase,則會(huì)阻塞程序,select的語(yǔ)法:
select {
???case communication clause?:
??????statement(s);?????
???case communication clause?:
??????statement(s);
???/*可以定義任意數(shù)量的 case */
???default : /*可選 */
??????statement(s);
}
說(shuō)明:
否則: 1.如果有default子句,則執(zhí)行該語(yǔ)句。
如果沒(méi)有default字句,select將阻塞,直到某個(gè)通信可以運(yùn)行;Go不會(huì)重新對(duì)channel或值進(jìn)行求值。
?
demo:
package main
?
import (
"fmt"
???"time"
)
?
func enqueue(q chan int) {
???time.Sleep(time.Second * 3)
??? q <- 10
??? close(q)
}
?
func main() {
??? var c =make(chan int)
??? go enqueue(c)
??? for {
??????? select {
??????????? casex, ok := <- c:
???????????????if ok {
???????????????????fmt.Println(x)
???????????????} else {
???????????????????fmt.Println("closed")
???????????????????return
???????????????}
???????????default:
???????????????fmt.Println("waiting")
???????????????time.Sleep(time.Second)
??????? }
??? }
}
?
關(guān)于合理使用goroutine,推薦一篇文章:http://www.cnblogs.com/yjf512/archive/2012/06/30/2571247.html
總結(jié)
以上是生活随笔為你收集整理的Go语言goroutine+channel+select简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 编译原理 总结
- 下一篇: golang基础-chan的select