package main
import (
"fmt"
"time"
)
var (
globalInt int
blocked int // times we checked while blocked
)
type T struct {
}
type semaphore chan T
func (s semaphore) Init(n int) {
for i := 0; i < n; i++ {
s <- T{}
}
}
func (s semaphore) decr() {
fmt.Printf("Decr (available): %d\n", s.Len())
<-s
}
func (s semaphore) incr() {
s <- T{}
fmt.Printf("Incr (available): %d\n", s.Len())
}
func (s semaphore) Len() int {
return len(s)
}
// Take increments number of references, thereby
// decrementing number of available resources.
// When there are 0 available resources, this should
// end-up blocking.
func (s semaphore) Take() {
s.decr()
}
// Release is opposite of Take and reduces number of
// taken resources thereby incrementing number of available
// resources.
func (s semaphore) Release() {
s.incr()
}
// Busy
func (s semaphore) Busy() bool {
return s.Len() == 0
}
func main() {
timeout := make(chan int)
go func() {
time.Sleep(5 * time.Second)
timeout <- 1
}()
sema := make(semaphore, 1)
sema.Init(1)
go func() {
sema.Take()
fmt.Println("(1)")
fmt.Printf("1.1 Before Change: %d\n", globalInt)
time.Sleep(2 * time.Second)
globalInt++
fmt.Printf("1.2 After Change: %d\n", globalInt)
sema.Release()
}()
go func() {
sema.Take()
fmt.Println("(2)")
fmt.Printf("2.1 Before Change: %d\n", globalInt)
globalInt = 10
fmt.Printf("2.2 After Change: %d\n", globalInt)
sema.Release()
}()
sel:
select {
case <-timeout:
fmt.Printf("blocked count: %d\n", blocked)
return
default:
blocked++
goto sel
}
}
golang Golang使用链表实现基本堆栈的示例
package main
import (
"fmt"
"sync"
)
type Node struct {
value int
next *Node
}
type StackOfInts struct {
head *Node
length int
sync.Mutex
}
func (s *StackOfInts) Push(n int) {
s.Lock()
defer s.Unlock()
this := s.head
s.head = &Node{
value: n,
next: this,
}
s.length++
}
func (s *StackOfInts) Pop() int {
s.Lock()
defer s.Unlock()
popped := s.head
s.head = s.head.next
s.length--
return popped.value
}
func (s *StackOfInts) Len() int {
s.Lock()
defer s.Unlock()
return s.length
}
func (s *StackOfInts) IsEmpty() bool {
s.Lock()
defer s.Unlock()
return s.head == nil
}
func NewStack() *StackOfInts {
return &StackOfInts{
head: nil,
}
}
func main() {
s := NewStack()
s.Push(10)
s.Push(20)
s.Push(30)
s.Push(40)
for s.Len() > 0 {
fmt.Println(s.Pop())
}
fmt.Println(s.IsEmpty())
}