1, why do you want to control the number of Goroutine?
Goroutine is good, but the number is too many, often bring a lot of trouble, such as exhaustion of system resources caused by the program crashes, or high CPU usage caused the system to be busy. Like what:
1 for i:=010000; i++ {2 go work ()3 }
2, in what way to control the number of Goroutine?
To determine the number of goroutine before each go, if the number is super, block go execution. The first thing to think about is the use of channels. Writes a value to the channel before each execution of the go, until the channel is full and blocks, as follows:
1 varCh Chanint2 3 func work () {4 //Do something5<-CH6 }7 8 Func Main () {9ch = make (chanint,Ten)Ten fori:=0; I <10000; i++ { OneCH <-1 A go work () - } -}
This allows the goroutine to run at the same time to be limited to 10. But the new problem arises because not all goroutine are executed, and after the main function exits, there are some goroutine that are forced to finish without execution. This time we need to use sync. Waitgroup. Use Waitgroup to wait for all goroutine to exit. As follows:
1 varWG *sync. Waitgroup2 3 func work () {4 defer WG. Done ()5 //Do something6 }7 8 Func Main () {9WG = &sync. waitgroup{}Ten fori:=0; I <10000; i++ { OneWg. ADD (1) A go work () - } -Wg. Wait ()//wait for all goroutine to exit the}
3, elegant use and control of the number of Goroutine
In summary, we encapsulate the code as follows:
1 Package Gpool2 3 Import (4 "Sync"5 )6 7Type poolstruct {8Queue Chanint9WG *sync. WaitgroupTen } One AFunc New (sizeint) *Pool { - ifSize <=0 { -Size =1 the } - return&pool{ -Queue:make (chanint, size), -WG: &sync. waitgroup{}, + } - } + AFunc (P *pool) Add (deltaint) { at forI: =0; i < Delta; i++ { -P.queue <-1 - } - forI: =0; i > Delta; i-- { -<-P.queue - } in P.wg.add (Delta) - } to +Func (P *pool) Done () { -<-P.queue the P.wg.done () * } $ Panax NotoginsengFunc (P *pool) Wait () { - p.wg.wait () the}
To segment the test code:
1 Package Gpool_test2 3 Import (4 "Runtime"5 "Testing"6 " Time"7 "Gpool"8 )9 TenFunc test_example (T *testing. T) { OnePool: = Gpool. New ( -) A println (runtime. Numgoroutine ()) - forI: =0; I < +; i++ { -Pool. ADD (1) the go func () { - Time . Sleep (time. Second) - println (runtime. Numgoroutine ()) - pool. Done () + }() - } + pool. Wait () A println (runtime. Numgoroutine ()) at}
Good job,over~
How to gracefully control the number of Goroutine