openlang

Посмотрите, пожалуйста, мою реализацию конвейера на go (ещё изучаю язык)

Всем привет,

Я изучаю go и его средства конкурентного выполнения, а “конвейер” — один из распространённых шаблонов. Вот моя реализация этого шаблона, буду благодарен за разбор и предложения, что можно улучшить

package main

import (
    "context"
    "fmt"
    "runtime"
    "sync"
    "time"
)

func generate(ctx context.Context, inputs chan<- int) {
    defer close(inputs)
    item := 0
    for {
        select {
        case inputs ← item:
            item++
            time.Sleep(60 * time.Millisecond)
        case <-ctx.Done():
            fmt.Println("Ending producer goroutine and inputs channel gracefuly.")
            return
        }
    }
}

func process(inputs <-chan int, outputs chan<- int, group *sync.WaitGroup) {
    defer group.Done()
    for item := range inputs {
        outputs ← item * item
    }
}

func collect(outputs <-chan int) {
    for square := range outputs {
        fmt.Printf("square %d\n", square)
    }
}

func finish(group *sync.WaitGroup, outputs chan<- int) {
    group.Wait()
    close(outputs)
    fmt.Println("Ending coordinator/worker goroutines and outputs channel gracefuly.")
}

func main() {
    ctx, cancel := context.WithTimeout(
        context.Background(),
        1800*time.Millisecond
    )
    defer cancel()

    inputs := make(chan int, 960)
    outputs := make(chan int, 960)

    go generate(ctx, inputs)

    var group sync.WaitGroup
    for range 4 {
        group.Add(1)
        go process(inputs, outputs, &group)
    }

    go finish(&group, outputs)

    collect(outputs)

    fmt.Printf("Pipeline drained completly !\n")
    fmt.Printf("Goroutine count : %d\n", runtime.NumGoroutine()) // expected to be 1
}

И ещё, какие важные и широко используемые шаблоны конкурентного выполнения стоит изучить, например pubsub.

Всего доброго,

FV

Переведено с английскогоПоказать оригинал

Разговор продолжается 3

Следуя доводам
  1. Ссылка на ответ

    group.Add(1) go process(inputs, outputs, &group)

    Небольшое улучшение — более новая форма wg.Run, показанная в Go by Example: WaitGroups (https://gobyexample.com/waitgroups), с которой wg.Add и wg.Done уже не нужны

    Хотя на сам ваш вопрос это толком не отвечает…

    Переведено с английскогоПоказать оригинал
  2. Ссылка на ответ

    Можно посмотреть другие реализации конвейеров Go и идеи, на которых основан этот шаблон. Тогда вы лучше поймёте проблему, прежде чем решать, какие изменения нужны вашей реализации…

    Вот мой скромный вклад…

    Переведено с английскогоПоказать оригинал
  3. Ссылка на ответ

    Если под “конвейером” вы понимаете что-то вроде конвейера оболочки Linux, то это не он. Замечательная черта таких конвейеров — скрытый механизм синхронизации. Поэтому наличие здесь кода Sync меня озадачивает.

    Переведено с английскогоПоказать оригинал

Другие стороны того же вопроса

  1. Преобразование функций в продолжения для глубоких обработчиков

    В примере глубоких обработчиков из документации есть такой абзац: Вычисление f само может выполнять эффекты. Когда f выполняе…

    Ответы 3Последняя активность ocaml