如何在 Go 中将 time.Time 变量转换为原子变量?

tar*_*raf 2 atomic go

在作为在线游戏的 RESTFUL Web 服务中,我将每个问题的开始时间存储在这样的全局变量中:var MyTime time.Time我应该在游戏的每个级别之后更新它。我的应用程序是分布式的,所以我想确保我的所有应用程序不会同时更新它。这就是为什么我决定让它原子化。其实我对 Golangsync/atomic包很熟悉。我尝试使用atomic.LoadPointer()方法,但它需要不安全的特定参数类型。你有其他办法吗?

更新: 好的,我这样解决了我的问题。我将时间变量定义为atomic.Value并使用原子加载和存储方法。这是代码: var myTime atomic.Value myTime.Store(newTime)和 load myTime.Load().(time.Time)

考虑到 Load() 方法返回接口,因此您应该在最后编写 (time.Time) 以便将其转换为 time.Time 类型。

Fli*_*mzy 5

不能这样做,因为time.Time是复合类型:

type Time struct {
    // wall and ext encode the wall time seconds, wall time nanoseconds,
    // and optional monotonic clock reading in nanoseconds.
    //
    // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
    // a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
    // The nanoseconds field is in the range [0, 999999999].
    // If the hasMonotonic bit is 0, then the 33-bit field must be zero
    // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
    // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
    // unsigned wall seconds since Jan 1 year 1885, and ext holds a
    // signed 64-bit monotonic clock reading, nanoseconds since process start.
    wall uint64
    ext  int64

    // loc specifies the Location that should be used to
    // determine the minute, hour, month, day, and year
    // that correspond to this Time.
    // The nil location means UTC.
    // All UTC times are represented with loc==nil, never loc==&utcLoc.
    loc *Location
}
Run Code Online (Sandbox Code Playgroud)

但是,您可以使用指针来执行此操作,因此*time.Time如果这适合您的需要,那也是可能的。但当然,这是不鼓励的,因为事实上atomic.LoadPointeratomic.StorePointer使用unsafe包来完成他们的魔法。

一个更好的方法,如果它对你有用的话,就是使用互斥锁来保护你的价值。有很多方法可以做到这一点,但一个最小的例子:

type MyTime struct {
    t  time.Time
    mu sync.RWMutex
}

func (t *MyTime) Time() time.Time {
    t.mu.RLock()
    defer t.mu.RUnlock()
    return t.t
}

func (t *MyTime) SetTime(tm time.Time) {
    t.mu.Lock()
    defer t.mu.Unlock()
    t.t = tm
}
Run Code Online (Sandbox Code Playgroud)