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  */