Паралельне програмування, використання го мови для створення монітору, синхронізації, критичної зони, керування зв*язками
Monitor — реалізує монітор через sync.Mutex, який відповідає за синхронізацію доступу до критичної секції.
CriticalSection — метод, який блокує доступ до ресурсів через mu.Lock() і звільняє після завершення через mu.Unlock() (за допомогою defer).
Горутини — паралельні завдання, що використовуються для запуску критичних секцій одночасно.
sync.WaitGroup — для синхронізації завершення горутин.
package main
import (
"fmt"
"sync"
"time"
)
const (
maxCharacters = 15
charA = 'A'
charB = 'B'
charC = 'C'
)
type Monitor struct {
sync.Mutex
cond *sync.Cond
characters string
aCount int
done bool
}
func NewMonitor() *Monitor {
m := &Monitor{
characters: "*",
}
m.cond = sync.NewCond(&m.Mutex)
return m
}
func (m *Monitor) addA(wg *sync.WaitGroup) {
defer wg.Done()
for {
m.Lock()
if len(m.characters)-1 >= maxCharacters {
m.done = true // Mark as done
m.cond.Broadcast() // Notify other processes to wake up
m.Unlock()
return
}
m.characters += string(charA)
m.aCount++
fmt.Println(m.characters)
m.cond.Broadcast() // Notify other processes
m.Unlock()
time.Sleep(time.Millisecond * 100) // Simulate work
}
}
func (m *Monitor) addB(wg *sync.WaitGroup) {
defer wg.Done()
for {
m.Lock()
for m.aCount < 3 || len(m.characters)-1 >= maxCharacters {
if m.done { // Check if we're done
m.Unlock()
return
}
m.cond.Wait() // Wait until condition is met
}
m.characters += string(charB)
fmt.Println(m.characters)
m.Unlock()
time.Sleep(time.Millisecond * 150) // Simulate work
}
}
func (m *Monitor) addC(wg *sync.WaitGroup) {
defer wg.Done()
for {
m.Lock()
for m.aCount < 3 || len(m.characters)-1 >= maxCharacters {
if m.done { // Check if we're done
m.Unlock()
return
}
m.cond.Wait() // Wait until condition is met
}
m.characters += string(charC)
fmt.Println(m.characters)
m.Unlock()
time.Sleep(time.Millisecond * 200) // Simulate work
}
}
func main() {
monitor := NewMonitor()
var wg sync.WaitGroup
wg.Add(3) // Three processes
go monitor.addA(&wg)
go monitor.addB(&wg)
go monitor.addC(&wg)
wg.Wait() // Wait for all goroutines to finish
fmt.Println("Final string:", monitor.characters)
}












