用 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 {
    // エラー処理
  }

}
广告
将在 10 秒后关闭
bannerAds