2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -7,6 +7,13 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// counting semaphore implemented with a buffered channel
|
||||
type sem chan struct{}
|
||||
|
||||
func (s sem) acquire() { s <- struct{}{} }
|
||||
func (s sem) release() { <-s }
|
||||
func (s sem) count() int { return cap(s) - len(s) }
|
||||
|
||||
// log package serializes output
|
||||
var fmt = log.New(os.Stdout, "", 0)
|
||||
|
||||
|
|
@ -15,11 +22,7 @@ const nRooms = 10
|
|||
const nStudents = 20
|
||||
|
||||
func main() {
|
||||
// buffered channel used as a counting semaphore
|
||||
rooms := make(chan int, nRooms)
|
||||
for i := 0; i < nRooms; i++ {
|
||||
rooms <- 1
|
||||
}
|
||||
rooms := make(sem, nRooms)
|
||||
// WaitGroup used to wait for all students to have studied
|
||||
// before terminating program
|
||||
var studied sync.WaitGroup
|
||||
|
|
@ -31,12 +34,12 @@ func main() {
|
|||
studied.Wait()
|
||||
}
|
||||
|
||||
func student(rooms chan int, studied *sync.WaitGroup) {
|
||||
<-rooms // acquire operation
|
||||
func student(rooms sem, studied *sync.WaitGroup) {
|
||||
rooms.acquire()
|
||||
// report per task descrption. also exercise count operation
|
||||
fmt.Printf("Room entered. Count is %d. Studying...\n",
|
||||
len(rooms)) // len function provides count operation
|
||||
rooms.count())
|
||||
time.Sleep(2 * time.Second) // sleep per task description
|
||||
rooms <- 1 // release operation
|
||||
studied.Done() // signal that student is done
|
||||
rooms.release()
|
||||
studied.Done() // signal that student is done
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,40 +4,41 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
var fmt = log.New(os.Stdout, "", 0)
|
||||
|
||||
type countSem struct {
|
||||
c int32
|
||||
cond *sync.Cond
|
||||
int
|
||||
sync.Cond
|
||||
}
|
||||
|
||||
func newCount(n int) *countSem {
|
||||
return &countSem{int32(n), sync.NewCond(new(sync.Mutex))}
|
||||
return &countSem{n, sync.Cond{L: &sync.Mutex{}}}
|
||||
}
|
||||
|
||||
func (cs *countSem) count() int {
|
||||
return int(atomic.LoadInt32(&cs.c))
|
||||
cs.L.Lock()
|
||||
c := cs.int
|
||||
cs.L.Unlock()
|
||||
return c
|
||||
}
|
||||
|
||||
func (cs *countSem) acquire() {
|
||||
if atomic.AddInt32(&cs.c, -1) < 0 {
|
||||
atomic.AddInt32(&cs.c, 1)
|
||||
cs.cond.L.Lock()
|
||||
for atomic.AddInt32(&cs.c, -1) < 0 {
|
||||
atomic.AddInt32(&cs.c, 1)
|
||||
cs.cond.Wait()
|
||||
}
|
||||
cs.cond.L.Unlock()
|
||||
cs.L.Lock()
|
||||
cs.int--
|
||||
for cs.int < 0 {
|
||||
cs.Wait()
|
||||
}
|
||||
cs.L.Unlock()
|
||||
}
|
||||
|
||||
func (cs *countSem) release() {
|
||||
atomic.AddInt32(&cs.c, 1)
|
||||
cs.cond.Signal()
|
||||
cs.L.Lock()
|
||||
cs.int++
|
||||
cs.L.Unlock()
|
||||
cs.Broadcast()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue