Last active
April 1, 2021 02:05
-
-
Save carmel/489a06b10445d984338b7b7e2bd2e5e8 to your computer and use it in GitHub Desktop.
golang限制Goroutine的数量(Limiting Goroutines)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pool | |
import ( | |
"sync" | |
) | |
// type Work func() | |
type WorkPool struct { | |
queue chan struct{} | |
wg *sync.WaitGroup | |
} | |
func NewPool(size int, wg *sync.WaitGroup) *WorkPool { | |
return &WorkPool{make(chan struct{}, size), wg} | |
} | |
func (p *WorkPool) Acquire() { | |
defer p.wg.Add(1) | |
p.queue <- struct{}{} | |
} | |
func (p *WorkPool) Release() { | |
defer p.wg.Done() | |
<-p.queue | |
} | |
func (p *WorkPool) Wait() { | |
defer close(p.queue) | |
p.wg.Wait() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pool | |
import ( | |
"context" | |
"crypto/sha256" | |
"fmt" | |
"runtime" | |
"sync" | |
"testing" | |
"golang.org/x/sync/semaphore" | |
// 使用semaphore时,发现多执行几次每次处理结果都不一样 | |
) | |
func DoSomething(d interface{}) { | |
fmt.Println("doing......", d) | |
} | |
func TestSemaphore(t *testing.T) { | |
data := []interface{}{1, 2, 3, 4, 5, 6, 7} // len == 10 | |
poolSize := runtime.NumCPU() // 4 thread CPU | |
sem := semaphore.NewWeighted(int64(poolSize)) | |
for _, d := range data { | |
_ = sem.Acquire(context.Background(), 1) | |
go func(d interface{}) { | |
DoSomething(d) | |
sem.Release(1) | |
}(d) | |
} | |
} | |
const text = `You may write me down in history | |
With your bitter, twisted lies, | |
You may trod me in the very dirt | |
But still, like dust, I'll rise.` | |
const poolSize = 100 | |
func BenchmarkWorkPool(b *testing.B) { | |
b.ReportAllocs() | |
pool := NewPool(poolSize, &sync.WaitGroup{}) | |
for n := 0; n < b.N; n++ { | |
// Fib(n) | |
pool.Acquire() | |
go func(n int) { | |
h := sha256.New() | |
h.Write([]byte(fmt.Sprintf("%d: %s", n, text))) | |
pool.Release() | |
}(n) | |
} | |
pool.Wait() | |
} | |
func BenchmarkSemaphore(b *testing.B) { | |
b.ReportAllocs() | |
sem := semaphore.NewWeighted(poolSize) | |
for n := 0; n < b.N; n++ { | |
_ = sem.Acquire(context.Background(), 1) | |
go func(n int) { | |
h := sha256.New() | |
h.Write([]byte(fmt.Sprintf("%d: %s", n, text))) | |
sem.Release(1) | |
}(n) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
semaphore
有个问题:对于同样的数据执行多次,发现每次执行的结果都不一样。