HW5 is completed

pull/5/head
Andrey Ivanov 2020-07-26 19:22:06 +03:00 committed by Andrey Ivanov
parent cce84208ae
commit 861085560f
2 changed files with 33 additions and 16 deletions

View File

@ -16,13 +16,16 @@ func RunMixed(tasks []Task, n int, m int) error {
wg.Add(n) wg.Add(n)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
go consMixed(ch, &wg, &errs, ignore) go consumer(ch, &wg, &errs, ignore)
} }
for _, task := range tasks { for _, task := range tasks {
errs.mx.RLock()
if !ignore && errs.count <= 0 { if !ignore && errs.count <= 0 {
errs.mx.RUnlock()
break break
} }
errs.mx.RUnlock()
ch <- task ch <- task
} }
close(ch) close(ch)
@ -34,15 +37,20 @@ func RunMixed(tasks []Task, n int, m int) error {
return nil return nil
} }
func consMixed(ch <-chan Task, wg *sync.WaitGroup, errs *Errors, ignore bool) { func consumer(ch <-chan Task, wg *sync.WaitGroup, errs *Errors, ignore bool) {
defer wg.Done() defer wg.Done()
for task := range ch { for task := range ch {
errs.mx.RLock()
if !ignore && errs.count <= 0 { if !ignore && errs.count <= 0 {
errs.mx.RUnlock()
return return
} }
errs.mx.RUnlock()
err := task() err := task()
if !ignore && err != nil { if !ignore && err != nil {
errs.mx.Lock()
errs.count-- errs.count--
errs.mx.Unlock()
} }
} }
} }

View File

@ -1,27 +1,36 @@
package hw05_parallel_execution //nolint:golint,stylecheck package hw05_parallel_execution //nolint:golint,stylecheck
import "sync"
func Run(tasks []Task, n int, m int) error { func Run(tasks []Task, n int, m int) error {
if m == -1 { if m == -1 {
m = len(tasks) m = len(tasks)
} }
pool := make(chan int, n) task, errs, wg, done := make(chan Task), make(chan error, len(tasks)), sync.WaitGroup{}, make(chan struct{})
errs := make(chan int) defer func() {
for _, task := range tasks { close(done)
pool <- 1 wg.Wait()
go func(task Task, errs chan int, pool chan int) { }()
if _, ok := <-errs; !ok { wg.Add(n)
return for i := 1; i <= n; i++ {
go func(task chan Task, errs chan error, wg *sync.WaitGroup, done chan struct{}) {
for {
select {
case <-done:
wg.Done()
return
case t := <-task:
if err := t(); err != nil {
errs <- err
}
}
} }
if task() != nil { }(task, errs, &wg, done)
errs <- 1 }
} for _, t := range tasks {
<-pool task <- t
}(task, errs, pool)
if len(errs) >= m { if len(errs) >= m {
close(errs)
return ErrErrorsLimitExceeded return ErrErrorsLimitExceeded
} }
} }
close(errs)
return nil return nil
} }