<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 一、channel是什么 * goroutine運行在相同的地址空間,因此訪問共享內存必須做好同步,處理好線程安全問題 * goroutine奉行通過通信來共享內存,而不是共享內存來通信 * channel是一個引用類型,用于多個goroutine通訊,其內部實現了同步,確保并發安全 * channel主要用域多個協程之間通信 ## 二、channel的基本使用 * channel可以用內置make()函數創建 * 定義一個channel時,也需要定義發送到channel的值的類型 make(chan 類型) make(chan 類型, 容量) * 當 capacity= 0 時,channel 是無緩沖阻塞讀寫的,當capacity> 0 時,channel 有緩沖、是非阻塞的,直到寫滿 capacity個元素才阻塞寫入 * channel通過操作符<-來接收和發送數據,發送和接收數據語法: channel <- value //發送value到channel <-channel //取出數據扔掉 x := <-channel //取出數據,給x x, ok := <-channel //功能同上,順便檢查一下通道 ## 三、channel實現主協程和子協程通信 ~~~ package main import ( "fmt" ) func main() { // 創建協程 h := make(chan int) // 創建子協程 go func(){ defer fmt.Println("子協程結束") fmt.Println("子協程正在運行") h <- 999 }() num := <-h fmt.Println("num=",num) fmt.Println("main結束") } ~~~ 運行結果: 子協程正在運行 子協程結束 num= 999 main結束 ## 四、無緩沖 channel ~~~ package main import ( "fmt" "time" ) func main() { //無緩沖通道 c := make(chan int, 0) fmt.Printf("len(c)=%d,cap(c)=%d\n", len(c), cap(c)) //子協程存數據 go func() { defer fmt.Println("子協程結束") //向通道添加數據 for i := 0; i < 3; i++ { c <- i fmt.Printf("子協程正在運行[%d]:"+"len(c)=%d,cap(c)=%d\n", i, len(c), cap(c)) } }() time.Sleep(2 * time.Second) //主協程取數據 for i := 0; i < 3; i++ { num := <-c fmt.Println("num = ", num) } fmt.Println("主協程結束") } ~~~ 運行結果: len(c)=0,cap(c)=0 num = 0 子協程正在運行[0]:len(c)=0,cap(c)=0 子協程正在運行[1]:len(c)=0,cap(c)=0 num = 1 num = 2 主協程結束 ## 五、有緩沖 channel ~~~ package main import ( "fmt" "time" ) func main() { //有緩沖通道 c := make(chan int, 3) fmt.Printf("len(c)=%d,cap(c)=%d\n", len(c), cap(c)) //子協程存數據 go func() { defer fmt.Println("子協程結束") //向通道添加數據 for i := 0; i < 3; i++ { c <- i fmt.Printf("子協程正在運行[%d]:"+"len(c)=%d,cap(c)=%d\n", i, len(c), cap(c)) } }() time.Sleep(2 * time.Second) //主協程取數據 for i := 0; i < 3; i++ { num := <-c fmt.Println("num = ", num) } fmt.Println("主協程結束") } ~~~ 執行結果: len(c)=0,cap(c)=3 子協程正在運行[0]:len(c)=1,cap(c)=3 子協程正在運行[1]:len(c)=2,cap(c)=3 子協程正在運行[2]:len(c)=3,cap(c)=3 子協程結束 num = 0 num = 1 num = 2 主協程結束 ## 六、close() * 可以通過內置的close()函數關閉channel * 通知取通道數據的地方,沒有數據了,不用取數據了 #### 沒有close() ~~~ package main import ( "fmt" ) func main() { c := make(chan int) //子協程存數據 go func() { for i := 0; i < 5; i++ { c <- i } }() //主協程取數據 for { if data, ok := <-c; ok { fmt.Println(data) } else { break } } fmt.Println("主協程結束") } ~~~ 這里的運行結果會出現報錯,因為我們的主協程是死循環,會一致執行 #### 有close() ~~~ package main import ( "fmt" ) func main() { c := make(chan int) //子協程存數據 go func() { for i := 0; i < 5; i++ { c <- i } close(c) }() //主協程取數據 for { if data, ok := <-c; ok { fmt.Println(data) } else { break } } fmt.Println("主協程結束") } ~~~ 運行結果: 0 1 2 3 4 主協程結束 注:這里子協程會有一個通知主協程的動作,如果沒有更多數據,子協程會通知主協程,沒有更多數據可以結束取數據的動作了 ## 七、單方向的channel ### 1、概念 * 默認情況下,通道是雙向的,也就是,既可以往里面發送數據也可以接收數據 * go可以定義單方向的通道,也就是只發送數據或者只接收數據,聲明如下 var ch1 chan int //正常 var ch2 chan<- float64 //只能寫float64 var ch3 <-chan int //只能讀int類型數據 * 可以將 channel 隱式轉換為單向隊列,只收或只發,不能將單向 channel 轉換為普通channel #### 普通實例1 ~~~ package main import ( "fmt" ) func main() { // 定義一個正常的通道 c := make(chan int,3) // 轉換為只寫通道 var send chan<- int =c // 轉化為只讀 var recv <-chan int =c // 寫數據 send <- 11 // 讀數據 <- recv fmt.Println("結束") } ~~~ #### 單方向的channel 可以用作生產者和消費者 ~~~ package main import "fmt" //生產者,只寫 func producter(out chan<- int) { defer close(out) for i := 0; i < 5; i++ { out <- i } } //消費者,只讀 func consumer(in <-chan int) { for num := range in { fmt.Println(num) } } func main() { //正常通道 c := make(chan int) //生產者 //可以將 channel 隱式轉換為單向隊列,只收或只發,不能將單向 channel 轉換為普通channel go producter(c) //消費者 consumer(c) fmt.Println("done") } ~~~ 執行結果: 0 1 2 3 4 done 注:可以將 channel 隱式轉換為單向隊列,只收或只發,不能將單向 channel 轉換為普通channel
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看