Skip to content

Commit

Permalink
Semaphore pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
lee501 committed Sep 5, 2019
1 parent a296c64 commit 97ec80a
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 4 deletions.
2 changes: 0 additions & 2 deletions 09-semaphore-pattern/samephore.go

This file was deleted.

52 changes: 52 additions & 0 deletions 09-semaphore-pattern/semaphore.go
@@ -0,0 +1,52 @@
package semaphore

import (
"errors"
"time"
)

/*
核心思想:
1.type interface 包含Acquire和release行为
2.定义结构体, 包含chan 和过期时间属性
3. 在Acquire中实现channel读入
4. 在release中channel 读出, 阻塞超时返回错误
*/
var (
ErrNoTickets = errors.New("semaphore: could not acquire semaphore")
ErrIllegalRelease = errors.New("semaphore: can't release semaphore without acquiring it first")
)
type Interface interface {
Acquire() error
Release() error
}
//定义结构体, 信号量使用chan struct{}
type Semaphore struct {
sem chan struct{}
timeout time.Duration
}

func (s *Semaphore) Acquire() error {
select {
case s.sem <- struct{}{}:
return nil
case <- time.After(s.timeout):
return ErrNoTickets
}
}

func (s *Semaphore) Release() error {
select {
case <- s.sem:
return nil
case <- time.After(s.timeout):
return ErrIllegalRelease
}
}

func New(tickets int, timeout time.Duration) Interface {
return &Semaphore{
sem: make(chan struct{}, tickets),
timeout: timeout,
}
}
34 changes: 34 additions & 0 deletions 09-semaphore-pattern/semaphore_test.go
@@ -0,0 +1,34 @@
package semaphore

import (
"fmt"
"testing"
"time"
)

func TestNoRelease(t *testing.T) {
ticket, timeout := 1, 2*time.Second
sem := New(ticket, timeout)

if err := sem.Acquire(); err != nil {
fmt.Println(err)
}

if err := sem.Release(); err != nil {
fmt.Println(err)
}
if err := sem.Release(); err != nil {
fmt.Println(err)
}
}

func TestNoTicket(t *testing.T) {
ticket, timeout := 0, 1 * time.Second
sem := New(ticket, timeout)

if err := sem.Acquire(); err != nil {
if err == ErrNoTickets {
fmt.Println(err)
}
}
}
15 changes: 13 additions & 2 deletions main.go
Expand Up @@ -16,6 +16,17 @@ func main() {
}
fmt.Println("jie")

var m struct{}
m = P{}
//type sem chan struct{}
s := make(chan struct{}, 1)
select {
case s <- struct{}{}:
fmt.Println("struct")
}

type sem chan struct{}
m := make(sem, 1)
select {
case m <- struct{}{}:
fmt.Println("struct1")
}
}

0 comments on commit 97ec80a

Please sign in to comment.