Как динамически определиться с количеством горутин, работающих над задачей - PullRequest
0 голосов
/ 12 февраля 2019

Я написал фиктивный код, чтобы продемонстрировать цель.

В коде 2 канала и 3 подпрограммы.

1 подпрограмма генерирует числа, основанные на том, делятся ли они на 100без остатка:

  • Если число делится на 100, оно выталкивает его на первый канал.

  • В противном случае оно выдвигается квторой канал.

2 потребителями этих каналов являются:

  • 1 - отвечает за потребление числа 1 ... 99 -101 ... 199 и т. Д.

  • Другая программа отвечает за 100, 200, 300 и т. Д.

Теперь, очевидно, одна программа имеет 99xбольше работы, чем другой горутин.Как это обрабатывается в Go?Если программа работает больше, чем другие, получает ли эта программа больше процессорного времени?Или я должен справиться с этой ситуацией, например, создать 99 горутин для канала, который требует больше ресурсов?(ради аргумента, рабочие места считаются идентичными)

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)

    go generator(ch1, ch2)
    go handler(ch1)
    go handler2(ch2)

    time.Sleep(1*time.Second)
}

func generator(chan1, chan2 chan int){
    for i:=0 ; ; i++{
        if i%100 == 0{
            chan1 <- i
        }else{
            chan2 <- i
        }
    }
}

func handler(number chan int){
    for _ = range number{
        num := <- number
        fmt.Println("Number divided by 100 is 0. ", num)
    }
}

func handler2(number chan int){
    for _ = range number{
        num := <- number
        fmt.Println("Number divided by 100 is not 0. ", num)
    }
}

Ответы [ 2 ]

0 голосов
/ 12 февраля 2019

Если на ch2 нечего читать, handler2 ничего не делает.В то же время handler1 занят обработкой того, что он читает из ch1.Это потребляет больше процессорного времени.

Было бы интересно, сколько времени потребуется от запуска трех подпрограмм до данных, доступных на каналах.Возможно, что generator выполнил всю свою работу до того, как handler1 и handler2 будут готовы к чтению с каналов.В этом случае handler2 скоро завершит свою работу, в то время как handler1 еще есть над чем поработать.

Вы, конечно, можете создать больше подпрограмм из handler1, которые будут обрабатывать данные в виде раунда.Робиновая манера.В зависимости от характера работы это может улучшить или ухудшить общую производительность.

Кстати, generator должно close и ch1 и ch2, когда все написано.

0 голосов
/ 12 февраля 2019

Сколько ресурсов ЦП получает подпрограмма, зависит от многих вещей.

В общем, мы можем сказать, что подпрограмма, которая обрабатывает только числа, делимые на 100, скорее всего будет ждать намного больше, чемДругой.Вы не должны беспокоиться об этом, поскольку ожидание элемента в канале не требует ресурсов ЦП, поэтому, если у вас «достаточно» других подпрограмм, для которых есть задачи, они могут использовать ваш ЦП.

Ваш примерэто просто по понятным причинам, но в реальном примере было бы выгоднее абстрагировать ваши задачи в общие задачи (например, обработка любого числа может быть задачей), создать и использовать общий рабочий пул и отправить все задачи для выполненияв бассейн.Таким образом, независимо от того, сколько у пула имеется подпрограмм, если есть работа, и есть свободная (ожидающая) подпрограмма, она выполнит задачу, максимально используя ваш ресурс ЦП.Обработчик заданий (исполнитель) должен знать, что делать с числом, равным 100 или 101.

. Пример того, как можно реализовать такой пул подпрограмм, см. идиоматический рабочий пул потоков в Go?

...