<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                channel 是 CSP 模式的具體實現,用于多個 goroutine 通訊。 其內部實現了同步,確保并發安全。多個goroutine同時訪問,不需要加鎖。 由于管道容量是5,開啟go寫入10個數據,再寫入5個數據,會阻塞,然而read每秒會讀取一個,然后在會寫入一個數據。 ~~~ package main import ( "fmt" "time" ) func write(ch chan int) { for i := 0; i < 10; i++ { ch <- i fmt.Println("put data:", i) } } func read(ch chan int) { for { var b int b = <-ch fmt.Println(b) time.Sleep(time.Second) } } func main() { intChan := make(chan int, 5) go write(intChan) go read(intChan) time.Sleep(10 * time.Second) } ~~~ 輸出結果: ~~~ put data: 0 put data: 1 put data: 2 put data: 3 put data: 4 put data: 5 0 1 put data: 6 2 put data: 7 3 put data: 8 4 put data: 9 5 6 7 8 9 ~~~ 默認為同步模式,需要發送和接收配對。否則會被阻塞,直到另一方準備好后被喚醒。 ~~~ package main import "fmt" func main() { data := make(chan int) // 數據交換隊列 exit := make(chan bool) // 退出通知 go func() { for d := range data { // 從隊列迭代接收數據,直到 close 。 fmt.Println(d) } fmt.Println("recv over.") exit <- true // 發出退出通知。 }() data <- 1 // 發送數據。 data <- 2 data <- 3 close(data) // 關閉隊列。 fmt.Println("send over.") <-exit // 等待退出通知。 } ~~~ 輸出結果: ~~~ 1 2 send over. 3 recv over. ~~~ 異步方式通過判斷緩沖區來決定是否阻塞。如果緩沖區已滿,發送被阻塞;緩沖區為空,接收被阻塞。 通常情況下,異步 channel 可減少排隊阻塞,具備更高的效率。但應該考慮使用指針規避大對象拷貝,將多個元素打包,減小緩沖區大小等。 ~~~ package main import ( "fmt" ) func main() { data := make(chan int, 3) // 緩沖區可以存儲 3 個元素 exit := make(chan bool) data <- 1 // 在緩沖區未滿前,不會阻塞。 data <- 2 data <- 3 go func() { for d := range data { // 在緩沖區未空前,不會阻塞。 fmt.Println(d) } exit <- true }() data <- 4 // 如果緩沖區已滿,阻塞。 data <- 5 close(data) <-exit } ~~~ 輸出結果: ~~~ 1 2 3 4 5 ~~~ channel選擇 : 如果需要同時處理多個 channel,可使用 select 語句。它隨機選擇一個可用 channel 做收發操作,或執行 default case。 ~~~ package main import ( "fmt" "os" ) func main() { a, b := make(chan int, 3), make(chan int) go func() { v, ok, s := 0, false, "" for { select { case v, ok = <-a: s = "a" case v, ok = <-b: s = "b" } if ok { fmt.Println(s, v) } else { os.Exit(0) } } }() for i := 0; i < 5; i++ { select { // 隨機選擇可 channel,接收數據。 case a <- i: case b <- i: } } close(a) select {} // 沒有可用 channel,阻塞 main goroutine。 } ~~~ 輸出結果: ~~~ // 每次運行輸出結果都不同 b 3 a 0 a 1 a 2 b 4 ~~~ 在循環中使用 select default case 需要小心,避免形成洪水。 模式 :用簡單工廠模式打包并發任務和 channel。 ~~~ package main import ( "math/rand" "time" ) func NewTest() chan int { c := make(chan int) rand.Seed(time.Now().UnixNano()) go func() { time.Sleep(time.Second) c <- rand.Int() }() return c } func main() { t := NewTest() println(<-t) // 等待 goroutine 結束返回。 } ~~~ 用 channel 實現信號量 (semaphore)。 ~~~ package main import ( "fmt" "runtime" "sync" ) func main() { runtime.GOMAXPROCS(2) wg := sync.WaitGroup{} wg.Add(3) sem := make(chan int, 1) for i := 0; i < 3; i++ { go func(id int) { defer wg.Done() sem <- 1 // 向 sem 發送數據,阻塞或者成功。 for x := 0; x < 3; x++ { fmt.Println(id, x) } <-sem // 接收數據,使得其他阻塞 goroutine 可以發送數據。 }(i) } wg.Wait() } ~~~ 輸出結果: ~~~ // 每次運行輸出結果都不同 0 0 0 1 0 2 2 0 2 1 2 2 1 0 1 1 1 2 ~~~ 用 closed channel 發出退出通知。 ~~~ package main import ( "sync" "time" ) func main() { var wg sync.WaitGroup quit := make(chan bool) for i := 0; i < 2; i++ { wg.Add(1) go func(id int) { defer wg.Done() task := func() { println(id, time.Now().Nanosecond()) time.Sleep(time.Second) } for { select { case <-quit: // closed channel 不會阻塞,因此可用作退出通知。 return default: // 執行正常任務。 task() } } }(i) } time.Sleep(time.Second * 5) // 讓測試 goroutine 運行一會。 close(quit) // 發出退出通知。 wg.Wait() } ~~~ 用 select 實現超時 (timeout)。 ~~~ package main import ( "fmt" "time" ) func main() { w := make(chan bool) c := make(chan int, 2) go func() { select { case v := <-c: fmt.Println(v) case <-time.After(time.Second * 3): fmt.Println("timeout.") } w <- true }() // c <- 1 // 注釋掉,引發 timeout。 <-w } ~~~
                  <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>

                              哎呀哎呀视频在线观看