Skip to content

请问这里的同步机制的使用是什么意思?和skeleton的使用有什么区别吗?使用标准库的timer要加同步处理吗?谢谢回答。 #135

Closed
@jjjjilyf

Description

@jjjjilyf

Leaf timer
Go 语言标准库提供了定时器的支持:

func AfterFunc(d Duration, f func()) *Timer
AfterFunc 会等待 d 时长后调用 f 函数,这里的 f 函数将在另外一个 goroutine 中执行。Leaf 提供了一个相同的 AfterFunc 函数,相比之下,f 函数在 AfterFunc 的调用 goroutine 中执行,这样就### 避免了同步机制的使用:

skeleton.AfterFunc(5 * time.Second, func() {
// ...
})
另外,Leaf timer 还支持 cron 表达式,用于实现诸如“每天 9 点执行”、“每周末 6 点执行”的逻辑。

更加详细的用法可以参考 leaf/timer。

Activity

name5566

name5566 commented on Nov 13, 2018

@name5566
Owner

正如文档所述的那样,标准库的 AfterFunc 中的 f 函数在另外一个 goroutine 中执行,所以,f 中的相关代码需要考虑使用同步机制。

jjjjilyf

jjjjilyf commented on Nov 14, 2018

@jjjjilyf
Author

谢谢回答,看到了源代码如下:
`// AfterFunc waits for the duration to elapse and then calls f
// in its own goroutine. It returns a Timer that can
// be used to cancel the call using its Stop method.
func AfterFunc(d Duration, f func()) *Timer {
t := &Timer{
r: runtimeTimer{
when: when(d),
f: goFunc,
arg: f,
},
}
startTimer(&t.r)
return t
}

func goFunc(arg interface{}, seq uintptr) {
go arg.(func())()
}`

可能我功力还不够,不太能想象的到,这个同步机制的使用场景。
现在的使用场景是用Skeleton.AfterFunc做帧同步的服务器驱动,每隔60毫秒发送一次消息驱动客户端帧逻辑帧处理,结果发现skeleton.AfterFun的的时间间隔并不稳定,99.N%以上都是60毫秒间隔左右,但有时候会跳到60毫秒的2倍或者3倍以上,目前的解决方法是:

`duration := time.Duration((b.bLogicInterval) * int64(time.Millisecond))
b.syncTimer = time.NewTimer(duration)

for {
	select {
	case <-b.syncTimer.C:
		b.SyncRoutine()
		if !b.isStop {
			b.syncTimer.Reset(duration)
		}
	}
}`

暂时未发现问题。

name5566

name5566 commented on Nov 14, 2018

@name5566
Owner

不使用同步可能引起问题,一定概率发生(可能通常都不发生),可能在用户量比较大的时候才出现。你发现的 Leaf 的 timer 会延时是因为某一些情况下,定时器到了触发时间了,但是现在还没机会执行,所以它就排队等待(可以认为是当前 goroutine 繁忙,需要处理其他代码),而 go 的 timer 额外开了一个 goroutine 来执行,所以无需等待(一定程度上来说是)。

实际上,这个问题是服务器帧率控制的问题。而帧率控制其实是动态的,而不是固定一个时间间隔,你可以看看 https://github.com/mangos/mangosd/blob/master/WorldRunnable.cpp#L78 的实现方法,思考一下。在  Leaf 中最好的帧率控制应该实现在 select 的 default 中。更多的东西就需要你自己探索了

jjjjilyf

jjjjilyf commented on Dec 5, 2018

@jjjjilyf
Author

多谢5566大神的指点,受益匪浅。看到的有点晚。。。

jjjjilyf

jjjjilyf commented on Dec 5, 2018

@jjjjilyf
Author

不使用同步可能引起问题,一定概率发生(可能通常都不发生),可能在用户量比较大的时候才出现。你发现的 Leaf 的 timer 会延时是因为某一些情况下,定时器到了触发时间了,但是现在还没机会执行,所以它就排队等待(可以认为是当前 goroutine 繁忙,需要处理其他代码),而 go 的 timer 额外开了一个 goroutine 来执行,所以无需等待(一定程度上来说是)。

实际上,这个问题是服务器帧率控制的问题。而帧率控制其实是动态的,而不是固定一个时间间隔,你可以看看 https://github.com/mangos/mangosd/blob/master/WorldRunnable.cpp#L78 的实现方法,思考一下。在  Leaf 中最好的帧率控制应该实现在 select 的 default 中。更多的东西就需要你自己探索了

Thanks♪(・ω・)ノ

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @name5566@jjjjilyf

        Issue actions

          请问这里的同步机制的使用是什么意思?和skeleton的使用有什么区别吗?使用标准库的timer要加同步处理吗?谢谢回答。 · Issue #135 · name5566/leaf