tudo pronto
[3hU9fRjo95.git] / pc_monitor.go~
blob354221b7cd810d0cd9b236b63d244be10827a584
1 /* pc_monitor.go */
3 package main
5 import (
6         . "fmt"
7         "crypto/rand"
8         "time"
9         . "sync"
12 func random_between (begin, end int64) int64 {
13         random_byte := make([]byte, 1)
14         rand.Read(random_byte)
15         return int64(random_byte[0]) % (end - begin + 1) + begin
18 func random_sleep () {
19         time.Sleep(random_between(0, MAX_SLEEP_TIME) * 10e7)
22 func signal (channel chan int) {
23         if len(channel) < cap(channel) || cap(channel) == 0 {
24                 channel <- 0
25         }
28 func wait (channel chan int) {
29         <-channel
32 const (
33         MAX_SLEEP_TIME = 5
34         BUFFER_SIZE = 5
37 type Monitor struct {
38         mutex *Mutex
39         empty, full chan int
40         buffer []int
41         front, rear, count int
44 var monitor *Monitor
46 func newMonitor () *Monitor {
47         return &Monitor {
48                 new(Mutex),
49                 make(chan int, BUFFER_SIZE),
50                 make(chan int, BUFFER_SIZE),
51                 make([]int, BUFFER_SIZE),
52                 0, 0, 0 }
55 func (m *Monitor) produce (i int) {
56         m.mutex.Lock()
57                 for m.count == BUFFER_SIZE { // buffer cheio?
58                         m.mutex.Unlock()
59                         wait(m.empty)    // (quase) uma variável de condição
60                         m.mutex.Lock()
61                 }
62                 Println("producing:", i)
63                 m.buffer[m.rear] = i
64                 m.rear = (m.rear + 1) % BUFFER_SIZE
65                 m.count++
66                 signal(m.full)
67         m.mutex.Unlock()
70 func (m *Monitor) consume () {
71         m.mutex.Lock()
72                 for m.count == 0 { // buffer vazio?
73                         m.mutex.Unlock()
74                         wait(m.full)            // (quase) uma variável de condição
75                         m.mutex.Lock()
76                 }
77                 v := m.buffer[m.front]
78                 m.front = (m.front + 1) % BUFFER_SIZE
79                 m.count--
80                 Println("\t\t\tconsuming:", v)
81                 signal(m.empty)
82         m.mutex.Unlock()
85 func producer () {
86         for i := 0; ; i++ { // laço infinito
87                 monitor.produce(i)
88                 random_sleep()
89         }
92 func consumer () {
93         for { // laço infinito
94                 monitor.consume()
95                 random_sleep()
96         }
99 func main () {
100         monitor = newMonitor()
101         go producer()
102         go consumer()
103         wait(make(chan int)) // espera indefinidamente