用 Golang 实现信号量
首先
-
- chan を使った semaphore をループ処理のなかで使っていた
-
- for 1ループごとに defer したいが func 抜ける時しか実行されない
- そうだ、無名関数で囲もう
跳色灯
type Semaphore struct {
sem chan struct{}
}
func NewSemaphore(size int) *Semaphore {
return &Semaphore{
sem: make(chan struct{}, size),
}
}
func (s *Semaphore) V() {
s.sem <- struct{}{}
}
func (s *Semaphore) P() {
<-s.sem
}
正常情况下推迟
for {
sem.V()
defer sem.P() // 当然まともに動かない
// 途中で抜ける
if err != nil {
continue
}
// 何か処理
}
尝试使用匿名函数来包围
for {
func() {
sem.V()
defer sem.P()
// 途中で抜けてもOK
if err != nil {
return
}
// 何か処理
}()
}
尝试将其包装成Wrap函数。
type Semaphore struct {
sem chan struct{}
}
func NewSemaphore(size int) *Semaphore {
return &Semaphore{
sem: make(chan struct{}, size),
}
}
func (s *Semaphore) V() {
s.sem <- struct{}{}
}
func (s *Semaphore) P() {
<-s.sem
}
func (s *Semaphore) Wrap(f func() error) chan error {
errChan := make(chan error, 1)
s.sem <- struct{}{}
errChan <- f()
close(errChan)
<-s.sem
return errChan
}
终态
for {
ec := sem.Wrap(func() error {
// 途中で抜けてもOK
if err != nil {
return
}
// 何か処理
})
if err := <- ec; err != nil {
// エラー処理
}
}