github.com/maikovskiys/l1tasks@v0.0.0-20230927052451-6436d7687dc9/develop/dev04/main.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "os/signal" 7 "sync" 8 ) 9 10 /* 11 Реализовать постоянную запись данных в канал (главный поток). 12 Реализовать набор из N воркеров, которые читают произвольные данные из канала и выводят в stdout. 13 Необходима возможность выбора количества воркеров при старте. 14 15 Программа должна завершаться по нажатию Ctrl+C. Выбрать и обосновать способ завершения работы всех воркеров. 16 */ 17 func main() { 18 wg := &sync.WaitGroup{} 19 sigch := make(chan os.Signal, 1) 20 signal.Notify(sigch, os.Interrupt) 21 ch := make(chan int, 10) 22 fmt.Println("select number of workers:") 23 var val int 24 fmt.Scan(&val) 25 for i := 1; i != val+1; i++ { 26 worker := i 27 wg.Add(1) 28 go func(int, chan int, chan os.Signal) { 29 for v := range ch { 30 fmt.Println("worker №:", worker) 31 fmt.Println("value from ch:", v) 32 } 33 wg.Done() 34 fmt.Println("worker done", worker) 35 }(worker, ch, sigch) 36 } 37 i := 0 38 for { 39 select { 40 case <-sigch: 41 fmt.Println("exit by signal") 42 close(ch) 43 wg.Wait() 44 fmt.Println("workers end") 45 close(sigch) 46 return 47 default: 48 ch <- i 49 i++ 50 } 51 52 } 53 54 } 55 56 /* 57 воркеры завершают свою работу только после закрытия канала с данными. 58 канал закрывается, воркеры доделывают работу, закрываются, как только последний воркер закрылся, выходим из main 59 */