测试信号量实现时出错

Error when testing semaphore implementation

我正在练习并发编程,我已经着手在 go 中实现多种模式和结构。我还添加了测试,其中我将信号量用作互斥量以增加共享计数器。我的实现显然有问题,因为在 运行 测试文件几次之后,一些测试通过了,但另一些测试失败了。 我的猜测是,不知何故,多个线程在没有阻塞的情况下通过了 Wait() 调用,并且可以并发访问计数器变量,但我不知道为什么。感谢您的帮助!

semaphore.go

package semaphore

import (
    "sync"
)

type Semaphore struct {
    capacity int

    count int
    sync.Mutex
    condition chan bool
}

func (s *Semaphore) Wait() {
    s.Lock()
    defer s.Unlock()

    if s.count == s.capacity {
        s.Unlock()
        <-s.condition
        s.Lock()
    }

    s.count++

}

func (s *Semaphore) Signal() {
    s.Lock()
    defer s.Unlock()

    select {
    case s.condition <- true:
    default:
    }

    s.count--

}

func NewSemaphore(n int) *Semaphore {
    return &Semaphore{count: 0, capacity: n, condition: make(chan bool)}
}

semaphore_test.go

package semaphore

import (
    "sync"
    "testing"
)

func TestMutexSemaphore(t *testing.T) {

    s := NewSemaphore(1)
    wg := sync.WaitGroup{}
    sharedCounter := 0
    iters := 25
    n := 20

    testfun := func(mutex *Semaphore) {
        defer wg.Done()
        for j := 0; j < iters; j++ {
            s.Wait()
            sharedCounter++
            s.Signal()
        }

    }
    wg.Add(n)
    for i := 0; i < n; i++ {
        go testfun(s)
    }

    wg.Wait()
    if sharedCounter != iters*n {
        t.Errorf("Bad counter value:%d expected %d", sharedCounter, n*iters)
    }

}


Wait中,当您唤醒并锁定时,无法保证条件仍然成立。锁定后,您应该再次检查条件:

   for s.count == s.capacity {
        s.Unlock()
        <-s.condition
        s.Lock()
    }

Signal你应该count--在叫醒别人之前。