Цикл Multi Go-Routine не выполняется должным образом - PullRequest
0 голосов
/ 25 января 2019

** РЕДАКТИРОВАТЬ, чтобы быть более кратким и ясным

Я довольно новичок в Go и абсолютно новичок в GoRoutines, но мне нужно добавить уровень параллелизма в мою программу, которую я создаю.

То, что я собираюсь сделать с этим, - это то, чтобы оба go func работали одновременно, и они технически. Однако они работают не так, как я ожидал.

Верхний go func должен запускаться каждые пять секунд в поисках нового задания и открытого устройства для запуска задания. Если есть новые рабочие места, он проверяет открытые устройства. Предполагая, что есть три новых задания и два открытых устройства, цикл for _, device := range должен выполняться дважды, назначая каждое задание устройству. Через пять секунд цикл снова запустится и увидит, что осталось выполнить одно задание, и проверит, открыты ли эти устройства для запуска задания. Между тем я ожидаю, что функция subSSH будет вызываться постоянно.

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

go func() {
    for {
        duration := 5 * time.Second
        for x := range time.Tick(duration) {//this loop runs every five seconds
            newJobs := checkForNew(jobcoll)
            if len(newJobs) != 0 {
                openPool := checkPoolDeviceStatus(poolcoll)
                for _, device := range openDevices {
                    //for each open device this loop should run once

                }
            }
        }
    }
}()

go func() {
    subSSH(subChannel, jobcoll, poolcoll)
}()

Я попытался добавить группы ожидания и добавить новое ожидание для числа новых заданий, но это привело к тому, что цикл устройства вообще никогда не выполнялся.

Я думаю, что мне здесь не хватает чего-то очевидного, и любая помощь очень ценится! Спасибо!

1 Ответ

0 голосов
/ 25 января 2019

Вы находитесь на правильном пути с тикером, но у вас есть переменные в неправильных областях.У вас также есть вложенный цикл for, поэтому идите и удалите его.

Вам понадобится что-то вроде этого:

go func() {
    ticker := time.NewTicker(5 * time.Second) // setup outside the loop.
    for t := range ticker.C { // every time 5 seconds passes, this channel will fire.
        newJobs := checkForNew(jobcoll)
        if len(newJobs) != 0 {
            openPool := checkPoolDeviceStatus(poolcoll)
            for _, device := range openDevices {
                // the thing should occur.
            }
        }
    }
}()

Это должно сработать.См .: https://play.golang.org/p/zj6jdoduCcp

Если вы хотите непрерывно выполняющуюся подпрограмму, вам нужен непрерывный цикл.

// only executes once and quits.
go func() { doTheThing() }()

// executes continuously after each execution exit.
go func() { for { doTheThing() } }()

// "background" function
go func() { doTheThingThatNeverExits() }()

Запрограммированная подпрограмма предназначена для фонового процесса (чрезмерное упрощение).Goroutine - это просто удобная оболочка для простого параллелизма при вызове функций.

Редактировать: пропущен последний бит.

...