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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                在Golang中,Goroutine雖然很好,但是數量太多了,往往會帶來很多麻煩,比如耗盡系統資源導致程序崩潰,或者CPU使用率過高導致系統忙不過來。所以我們可以限制下Goroutine的數量,這樣就需要在每一次執行go之前判斷goroutine的數量,如果數量超了,就要阻塞go的執行。第一時間想到的就是使用通道。每次執行的go之前向通道寫入值,直到通道滿的時候就阻塞了, ``` package main import "fmt" var ch chan int func elegance(){ <-ch fmt.Println("the ch value receive",ch) } func main(){ ch = make(chan int,5) for i:=0;i<10;i++{ ch <-1 fmt.Println("the ch value send",ch) go elegance() fmt.Println("the result i",i) } } ``` 運行: ``` > go run goroutine.go the ch value send 0xc00009c000 the result i 0 the ch value send 0xc00009c000 the result i 1 the ch value send 0xc00009c000 the result i 2 the ch value send 0xc00009c000 the result i 3 the ch value send 0xc00009c000 the result i 4 the ch value send 0xc00009c000 the result i 5 the ch value send 0xc00009c000 the ch value receive 0xc00009c000 the result i 6 the ch value receive 0xc00009c000 the ch value send 0xc00009c000 the result i 7 the ch value send 0xc00009c000 the result i 8 the ch value send 0xc00009c000 the result i 9 the ch value send 0xc00009c000 the ch value receive 0xc00009c000 the ch value receive 0xc00009c000 the ch value receive 0xc00009c000 the result i 10 the ch value send 0xc00009c000 the result i 11 the ch value send 0xc00009c000 the result i 12 the ch value send 0xc00009c000 the result i 13 the ch value send 0xc00009c000 the ch value receive 0xc00009c000 the ch value receive 0xc00009c000 the ch value receive 0xc00009c000 the ch value receive 0xc00009c000 the result i 14 the ch value receive 0xc00009c000 ``` ``` > go run goroutine.go the ch value send 0xc00007e000 the result i 0 the ch value send 0xc00007e000 the result i 1 the ch value send 0xc00007e000 the result i 2 the ch value send 0xc00007e000 the result i 3 the ch value send 0xc00007e000 the ch value receive 0xc00007e000 the result i 4 the ch value send 0xc00007e000 the ch value receive 0xc00007e000 the result i 5 the ch value send 0xc00007e000 the ch value receive 0xc00007e000 the result i 6 the ch value send 0xc00007e000 the result i 7 the ch value send 0xc00007e000 the ch value receive 0xc00007e000 the ch value receive 0xc00007e000 the ch value receive 0xc00007e000 the result i 8 the ch value send 0xc00007e000 the result i 9 ``` 這樣每次同時運行的goroutine就被限制為5個了。但是新的問題于是就出現了,因為并不是所有的goroutine都執行完了,在main函數退出之后,還有一些goroutine沒有執行完就被強制結束了。這個時候我們就需要用到sync.WaitGroup。使用WaitGroup等待所有的goroutine退出。 ``` package main import ( "fmt" "runtime" "sync" "time" ) // Pool Goroutine Pool type Pool struct { queue chan int wg *sync.WaitGroup } // New 新建一個協程池 func NewPool(size int) *Pool{ if size <=0{ size = 1 } return &Pool{ queue:make(chan int,size), wg:&sync.WaitGroup{}, } } // Add 新增一個執行 func (p *Pool)Add(delta int){ // delta為正數就添加 for i :=0;i<delta;i++{ p.queue <-1 } // delta為負數就減少 for i:=0;i>delta;i--{ <-p.queue } p.wg.Add(delta) } // Done 執行完成減一 func (p *Pool) Done(){ <-p.queue p.wg.Done() } // Wait 等待Goroutine執行完畢 func (p *Pool) Wait(){ p.wg.Wait() } func main(){ // 這里限制5個并發 pool := NewPool(5) fmt.Println("the NumGoroutine begin is:",runtime.NumGoroutine()) for i:=0;i<20;i++{ pool.Add(1) go func(i int) { time.Sleep(time.Second) fmt.Println("the NumGoroutine continue is:",runtime.NumGoroutine()) pool.Done() }(i) } pool.Wait() fmt.Println("the NumGoroutine done is:",runtime.NumGoroutine()) } ``` 運行: ``` the NumGoroutine begin is: 1 the NumGoroutine continue is: 6 the NumGoroutine continue is: 7 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 6 the NumGoroutine continue is: 3 the NumGoroutine continue is: 2 the NumGoroutine done is: 1 ``` 其中,Go的GOMAXPROCS默認值已經設置為CPU的核數, 這里允許我們的Go程序充分使用機器的每一個CPU,最大程度的提高我們程序的并發性能。runtime.NumGoroutine函數在被調用后,會返回系統中的處于特定狀態的Goroutine的數量。這里的特指是指Grunnable\Gruning\Gsyscall\Gwaition。處于這些狀態的Groutine即被看做是活躍的或者說正在被調度。 這里需要注意下:垃圾回收所在Groutine的狀態也處于這個范圍內的話,也會被納入該計數器。
                  <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>

                              哎呀哎呀视频在线观看