Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
99 additions
and
4 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} | ||
} |
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