|
|
|
@ -4,8 +4,60 @@ import ( |
|
|
|
|
"fmt" |
|
|
|
|
"time" |
|
|
|
|
"flag" |
|
|
|
|
"sync" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
func Worker(name string, done chan<- int, stop <-chan int) { |
|
|
|
|
for i := 0; i < 10; i++ { |
|
|
|
|
select { |
|
|
|
|
case <-stop: |
|
|
|
|
fmt.Println("Worker stopped:", name) |
|
|
|
|
return |
|
|
|
|
default: |
|
|
|
|
time.Sleep(1 * time.Second) |
|
|
|
|
fmt.Println("TESTER #", name) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
done<- 1 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func Supervisor(id int, count int) { |
|
|
|
|
stop := make(chan int) |
|
|
|
|
var wg sync.WaitGroup |
|
|
|
|
|
|
|
|
|
for i := 0; i < count; i++ { |
|
|
|
|
wg.Add(1) |
|
|
|
|
go func() { |
|
|
|
|
defer wg.Done() |
|
|
|
|
|
|
|
|
|
for { |
|
|
|
|
workerDone := make(chan int) |
|
|
|
|
go Worker(fmt.Sprintf("%d:%d", id, i), workerDone, stop) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
select { |
|
|
|
|
case <-workerDone: |
|
|
|
|
fmt.Println("Supervisor: Worker Done") |
|
|
|
|
time.Sleep(500 * time.Millisecond) |
|
|
|
|
case <-stop: |
|
|
|
|
fmt.Println("Supervisor: Stop") |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
go func() { |
|
|
|
|
// test shutdown
|
|
|
|
|
time.Sleep(10000 * time.Millisecond) |
|
|
|
|
close(stop) |
|
|
|
|
}() |
|
|
|
|
|
|
|
|
|
wg.Wait() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
|
count := flag.Int("count", 10, "Seconds to wait") |
|
|
|
|
id := flag.Int("id", 1, "Tester ID to use.") |
|
|
|
@ -13,8 +65,5 @@ func main() { |
|
|
|
|
|
|
|
|
|
fmt.Println(">>> TESTER STARTS, id=", *id, "count=", *count) |
|
|
|
|
|
|
|
|
|
for i := 0; i < *count; i++ { |
|
|
|
|
time.Sleep(1 * time.Second) |
|
|
|
|
fmt.Println("TESTER #", *id) |
|
|
|
|
} |
|
|
|
|
Supervisor(*id, *count) |
|
|
|
|
} |
|
|
|
|