日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
講解一下GoChannel

Channel是Go中的一個核心類型,可以看做是一個管道,通過它并發(fā)核心單元就可以發(fā)送或者接收數(shù)據(jù)進行通訊。

十余年的裕安網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整裕安建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)公司從事“裕安網(wǎng)站設(shè)計”,“裕安網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

它的操作符是箭頭

ch 

(箭頭的指向就是數(shù)據(jù)的流向)

就像 map 和 slice 數(shù)據(jù)類型一樣, channel必須先創(chuàng)建再使用:

ch := make(chan int)

Channel類型

Channel類型的定義格式如下:

ChannelType = ( "chan" | "chan" " | " "chan" ) ElementType . 

它包括三種類型的定義??蛇x的

chan T          // 可以接收和發(fā)送類型為 T 的數(shù)據(jù)
chan

chan

使用make初始化Channel,并且可以設(shè)置容量:

make(chan int, 100)

容量(capacity)代表Channel容納的最多的元素的數(shù)量,代表Channel的緩存的大小。 如果沒有設(shè)置容量,或者容量設(shè)置為0, 說明Channel沒有緩存,只有sender和receiver都準備好了后它們的通訊(communication)才會發(fā)生(Blocking)。如果設(shè)置了緩存,就有可能不發(fā)生阻塞, 只有buffer滿了后 send才會阻塞, 而只有緩存空了后receive才會阻塞。一個nil channel不會通信。

可以通過內(nèi)建的close方法可以關(guān)閉Channel。

你可以在多個goroutine從/往 一個channel 中 receive/send 數(shù)據(jù), 不必考慮額外的同步措施。

Channel可以作為一個先入先出(FIFO)的隊列,接收的數(shù)據(jù)和發(fā)送的數(shù)據(jù)的順序是一致的。

channel的 receive支持 multi-valued assignment,如

v, ok := 

send語句

send語句用來往Channel中發(fā)送數(shù)據(jù), 如ch

SendStmt = Channel " Expression . Channel  = Expression . 

在通訊(communication)開始前channel和expression必選先求值出來(evaluated),比如下面的(3+4)先計算出7然后再發(fā)送給channel。

c := make(chan int)
defer close(c)
go func() { c 

send被執(zhí)行前(proceed)通訊(communication)一直被阻塞著。如前所言,無緩存的channel只有在receiver準備好后send才被執(zhí)行。如果有緩存,并且緩存未滿,則send會被執(zhí)行。

往一個已經(jīng)被close的channel中繼續(xù)發(fā)送數(shù)據(jù)會導(dǎo)致run-time panic。

往nil channel中發(fā)送數(shù)據(jù)會一致被阻塞著。

receive 操作符

x, ok := 

如果OK 是false,表明接收的x是產(chǎn)生的零值,這個channel被關(guān)閉了或者為空。

blocking

默認情況下,發(fā)送和接收會一直阻塞著,直到另一方準備好。這種方式可以用來在gororutine中進行同步,而不必使用顯示的鎖或者條件變量。

如官方的例子中x, y :=

import "fmt"
func sum(s []int, c chan int) {
   sum := 0
   for _, v := range s {
       sum += v
   }
   c main() {
   s := []int{7, 2, 8, -9, 4, 0}
   c := make(chan int)
   go sum(s[:len(s)/2], c)
   go sum(s[len(s)/2:], c)
   x, y := 

Buffered Channels

make的第二個參數(shù)指定緩存的大?。篶h := make(chan int, 100)。

通過緩存的使用,可以盡量避免阻塞,提供應(yīng)用的性能。

Range

for …… range語句可以處理Channel。

func main() {
   go func() {
       time.Sleep(1 * time.Hour)
   }()
   c := make(chan int)
   go func() {
       for i := 0; i for i := range c {
       fmt.Println(i)
   }
   fmt.Println("Finished")
}

range c產(chǎn)生的迭代值為Channel中發(fā)送的值,它會一直迭代直到channel被關(guān)閉。上面的例子中如果把close(c)注釋掉,程序會一直阻塞在for …… range那一行。

select

select語句選擇一組可能的send操作和receive操作去處理。它類似switch,但是只是用來處理通訊(communication)操作。 它的case可以是send語句,也可以是receive語句,亦或者default。

receive語句可以將值賦值給一個或者兩個變量。它必須是一個receive操作。

最多允許有一個default case,它可以放在case列表的任何位置,盡管我們大部分會將它放在最后。

import "fmt"
func fibonacci(c, quit chan int) {
   x, y := 0, 1
   for {
       select {
       case c case "quit")
           return
       }
   }
}
func main() {
   c := make(chan int)
   quit := make(chan int)
   go func() {
       for i := 0; i 

如果有同時多個case去處理,比如同時有多個channel可以接收數(shù)據(jù),那么Go會偽隨機的選擇一個case處理(pseudo-random)。如果沒有case需要處理,則會選擇default去處理,如果default case存在的情況下。如果沒有default case,則select語句會阻塞,直到某個case需要處理。

需要注意的是,nil channel上的操作會一直被阻塞,如果沒有default case,只有nil channel的select會一直被阻塞。

select語句和switch語句一樣,它不是循環(huán),它只會選擇一個case來處理,如果想一直處理channel,你可以在外面加一個無限的for循環(huán):

for {
   select {
   case c case "quit")
       return
   }
}

timeout

select有很重要的一個應(yīng)用就是超時處理。 因為上面我們提到,如果沒有case需要處理,select語句就會一直阻塞著。這時候我們可能就需要一個超時操作,用來處理超時的情況。 下面這個例子我們會在2秒后往channel c1中發(fā)送一個數(shù)據(jù),但是select設(shè)置為1秒超時,因此我們會打印出timeout 1,而不是result 1。

import "time"
import "fmt"
func main() {
   c1 := make(chan string, 1)
   go func() {
       time.Sleep(time.Second * 2)
       c1 "result 1"
   }()
   select {
   case res := case "timeout 1")
   }
}

其實它利用的是time.After方法,它返回一個類型為

timer1 := time.NewTimer(time.Second * 2)
"Timer 1 expired")

當然如果你只是想單純的等待的話,可以使用time.Sleep來實現(xiàn)。

你還可以使用timer.Stop來停止計時器。

timer2 := time.NewTimer(time.Second)
go func() {
   "Timer 2 expired")
}()
stop2 := timer2.Stop()
if stop2 {
   fmt.Println("Timer 2 stopped")
}

ticker是一個定時觸發(fā)的計時器,它會以一個間隔(interval)往Channel發(fā)送一個事件(當前時間),而Channel的接收者可以以固定的時間間隔從Channel中讀取事件。下面的例子中ticker每500毫秒觸發(fā)一次,你可以觀察輸出的時間。

ticker := time.NewTicker(time.Millisecond * 500)
go func() {
   for t := range ticker.C {
       fmt.Println("Tick at", t)
   }
}()

類似timer, ticker也可以通過Stop方法來停止。一旦它停止,接收者不再會從channel中接收數(shù)據(jù)了。

close

內(nèi)建的close方法可以用來關(guān)閉channel。

總結(jié)一下channel關(guān)閉后sender的receiver操作。 如果channel c已經(jīng)被關(guān)閉,繼續(xù)往它發(fā)送數(shù)據(jù)會導(dǎo)致panic: send on closed channel:

import "time"
func main() {
   go func() {
       time.Sleep(time.Hour)
   }()
   c := make(chan int, 10)
   c 

但是從這個關(guān)閉的channel中不但可以讀取出已發(fā)送的數(shù)據(jù),還可以不斷的讀取零值:

c := make(chan int, 10)
c 

但是如果通過range讀取,channel關(guān)閉后for循環(huán)會跳出:

c := make(chan int, 10)
c for i := range c {
   fmt.Println(i)
}

通過i, ok :=

c := make(chan int, 10)
close(c)
i, ok := "%d, %t", i, ok) //0, false

同步

channel可以用在goroutine之間的同步。 下面的例子中main goroutine通過done channel等待worker完成任務(wù)。 worker做完任務(wù)后只需往channel發(fā)送一個數(shù)據(jù)就可以通知main goroutine任務(wù)完成。

import (
   "fmt"
   "time"
)
func worker(done chan bool) {
   time.Sleep(time.Second)
   // 通知任務(wù)已完成
   done true
}
func main() {
   done := make(chan bool, 1)
   go worker(done)
   // 等待任務(wù)完成
   done
}

當前文章:講解一下GoChannel
文章網(wǎng)址:http://www.5511xx.com/article/dheichp.html