Тикер не должен выполняться, если уже запущен - PullRequest
2 голосов
/ 19 февраля 2020

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

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(3*time.Second)
    flag := 0
    defer ticker.Stop()
    for {
        select {
        case t := <-ticker.C:
            flag = flag + 1
            if (flag % 2 ==0 ) {
                time.Sleep(time.Second*4)
            }   
            fmt.Println("Current time: ", t)
        }
    }
}

https://play.golang.org/p/2xV2MYInn4I

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

Как мне это сделать?

Ответы [ 2 ]

3 голосов
/ 19 февраля 2020

спит внутри одной и той же программы просто задерживает выполнение. тикер тем временем бежит в отдельной рутине. Таким образом, даже если вы используете глобальную переменную для поддержания состояния выполнения - она ​​не даст вам желаемого результата с помощью сна. Однако миграция всего «сна» в отдельную рутину дает:

package main

import (
    "fmt"
    "time"
)

type Tick struct {
    ticker *time.Ticker
    executing bool
}

func somethingYouWantToDo(tick *Tick, flag *int, t time.Time) {
    if tick.executing {
        return
    }

    tick.executing = true

    *flag = *flag + 1

    if (*flag % 2 ==0 ) {
                time.Sleep(time.Second*4)
    }   
        fmt.Println("Current time: ", t)
    tick.executing = false
}

func main() {
    tick := &Tick{
        ticker: time.NewTicker(3*time.Second),
    }
    flag := 0
    defer tick.ticker.Stop()
    for {
        select {
        case t := <-tick.ticker.C:
            go somethingYouWantToDo(tick, &flag, t)
        }
    }
}
// output
// Current time:  2009-11-10 23:00:03 +0000 UTC m=+3.000000001
// Current time:  2009-11-10 23:00:06 +0000 UTC m=+6.000000001
// Current time:  2009-11-10 23:00:12 +0000 UTC m=+12.000000001
// Current time:  2009-11-10 23:00:15 +0000 UTC m=+15.000000001
// Current time:  2009-11-10 23:00:21 +0000 UTC m=+21.000000001
// Current time:  2009-11-10 23:00:24 +0000 UTC m=+24.000000001
// Current time:  2009-11-10 23:00:30 +0000 UTC m=+30.000000001
// Current time:  2009-11-10 23:00:33 +0000 UTC m=+33.000000001
// Current time:  2009-11-10 23:00:39 +0000 UTC m=+39.000000001
// Current time:  2009-11-10 23:00:42 +0000 UTC m=+42.000000001
// Current time:  2009-11-10 23:00:48 +0000 UTC m=+48.000000001
// Current time:  2009-11-10 23:00:51 +0000 UTC m=+51.000000001
// Current time:  2009-11-10 23:00:57 +0000 UTC m=+57.000000001
// Current time:  2009-11-10 23:01:00 +0000 UTC m=+60.000000001
// Current time:  2009-11-10 23:01:06 +0000 UTC m=+66.000000001
// Current time:  2009-11-10 23:01:09 +0000 UTC m=+69.000000001

Попробуйте на детской площадке

3 голосов
/ 19 февраля 2020

Канал тикера буферизуется, поэтому вы можете видеть сразу несколько триггеров один за другим. Вы можете предотвратить это, просто передав значения тикера в небуферизованный канал (учтите также, что значение time.Time, полученное от тикера, - это не текущее время, а время последнего тика):

package main

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan time.Time) // unbuffered
    ticker := time.NewTicker(3 * time.Second)
    defer ticker.Stop()

    go func() {
        for t := range ticker.C {
            select {
            case c <- t:
            default:
            }
        }
    }()

    for flag := 0; flag < 8; flag++ {
        <-c

        if flag%2 == 0 {
            time.Sleep(time.Second * 4)
        }
        fmt.Println("Current time: ", time.Now())
    }
}

// Output:
// Current time:  2020-02-19 12:21:57.095433032 +0100 CET m=+3.000213350
// Current time:  2020-02-19 12:22:04.095585208 +0100 CET m=+10.000365520
// Current time:  2020-02-19 12:22:06.095363327 +0100 CET m=+12.000143680
// Current time:  2020-02-19 12:22:13.095605268 +0100 CET m=+19.000385598
// Current time:  2020-02-19 12:22:15.095371885 +0100 CET m=+21.000152174
// Current time:  2020-02-19 12:22:22.095537562 +0100 CET m=+28.000317857
// Current time:  2020-02-19 12:22:24.095431317 +0100 CET m=+30.000211625
// Current time:  2020-02-19 12:22:31.095524308 +0100 CET m=+37.000304595

Попробуйте на детской площадке: https://play.golang.org/p/jDe5uJiRVe2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...