-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCounterSecGoDo.go
130 lines (116 loc) · 3.72 KB
/
CounterSecGoDo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
const (
allsec int = 10
maxtimefindProducts int = 5
maxcolCustQ int = 2
maxtimeQ int = 5
maxcolCustEnter = 10
)
var (
chsec [allsec + maxtimeQ]chan struct{} //событие для постановки в очередь в кассу
chsecQ [allsec + maxtimeQ]chan struct{} //событие для выхода с кассы
maxcolLiveCust int
mu = sync.Mutex{}
colCust int
colLiveCust int
queue [10]int
maxcashDesk int
)
func Queue(sec int, id int, wg *sync.WaitGroup) {
defer wg.Done()
var qcurrent int
r := rand.Intn(maxtimeQ) + 1
secOut := sec + r //время покинуть магазин
find := false
for i := range queue { //поиск приемлемой кассы
mu.Lock()
if queue[i] < maxcolCustQ { //в кассе меньше N человек
find = true
queue[i]++
qcurrent = i
if maxcashDesk < i {
maxcashDesk = i
}
fmt.Println(id, " Покупатель", queue[i], "-й в очереди на кассе N-", qcurrent)
mu.Unlock() //необходимость
break
}
mu.Unlock()
}
if !find {
fmt.Println("Покупателю ", id, " Касс не хватает!!!")
}
select {
case <-chsecQ[secOut]:
mu.Lock()
queue[qcurrent]--
mu.Unlock()
fmt.Println(id, " Покупатель покинул магазин")
}
mu.Lock()
colLiveCust--
mu.Unlock()
}
func newCustomer(sec int, colCustwg *sync.WaitGroup) {
defer colCustwg.Done()
r := rand.Intn(maxtimefindProducts) + 1 //время на поиск товаров
secFindProducts := r + sec //время пойти к кассе
mu.Lock()
colCust++ //+1 покупатель в магазине
id := colCust //номер покупателя
mu.Unlock()
fmt.Printf("Покупатель N-%v хочет зайти в магазин в %v сек, нужно %v сек на покупки\n", id, sec, r)
enter := false
if secFindProducts < allsec { // успеет ли покупатель до закрытия магазина
enter = true
mu.Lock()
colLiveCust++
if maxcolLiveCust < colLiveCust {
maxcolLiveCust = colLiveCust
}
mu.Unlock()
select {
case <-chsec[secFindProducts]: //прослушиваем канал (эхо) отвечающий за текущую секунду
fmt.Printf("N-%v подошел к кассе в %v сек\n", id, secFindProducts)
qwg := sync.WaitGroup{}
qwg.Add(1)
go Queue(secFindProducts, id, &qwg)
qwg.Wait()
return
}
}
if !enter {
fmt.Printf("!!!Покупатель N-%v не успел в магазин\n", id)
}
}
func main() {
for i := range chsec { //иннициализация каналов (эхо) всех сек работы магазина
chsec[i] = make(chan struct{}) //не уверен, что надо
chsecQ[i] = make(chan struct{}) //...
}
colCustwg := sync.WaitGroup{}
for i := 0; i < allsec+maxtimeQ; i++ { //виртуальный таймер посекундный
if i < allsec {
r := rand.Intn(maxcolCustEnter)
for j := 0; j < r; j++ {
colCustwg.Add(1)
go newCustomer(i, &colCustwg) //запуск покупателя в магазин
}
close(chsec[i]) //опопвещение
close(chsecQ[i]) //...
<-time.After(time.Millisecond * 10)
} else {
close(chsecQ[i]) //...
<-time.After(time.Millisecond * 10)
}
}
colCustwg.Wait()
fmt.Println("Всего покупателей ", colCust)
fmt.Printf("Done максимальное кол-во посетителей в магазине %v , текущее кол-во посетителей в магаине %v, мин. касс %v", maxcolLiveCust, colLiveCust, maxcashDesk+1)
}