我一直在尝试在 Go 中创建一个简单的事件循环包装器。但是我被难住了,我应该如何跟踪当前线程中的操作? 我希望 CurrentTick 运行一个函数,即使调用函数退出,在 CurrentTick 运行的所有函数退出之前也不会开始下一个报价。我想我可能会使用互斥锁来监视线程数,但我意识到如果我一遍又一遍地检查它会限制 CPU。如果我使用 time.Sleep 它将是潜伏的。你会如何解决这个问题?
package eventloop
import (
"reflect"
)
type eventLoop *struct{
functions []reflect.Value
addFunc chan<-/*3*/ reflect.Value
mutex chan/*1*/ bool
threads int
}
func NewEventLoop() eventLoop {
var funcs chan reflect.Value
loop := eventLoop{
[]Reflect.Value{},
funcs = make(chan reflect.Value, 3),
make(chan bool, 1),
0,
}
go func(){
for {
this.mutex <- 1
if threads == 0 {
}
}
}
}
func (this eventLoop) NextTick(f func()) {
this.addFunc <- reflect.ValueOf(f)
}
func (this eventLoop) CurrentTick(f func()) {
this.mutex <- 1
threads += 1
<-this.mutex
go func() {
f()
this.mutex <- 1
threads -= 1
<-this.mutex
}()
}
最佳答案
如果我理解你的意图,我认为你把事情复杂化了。我会这样做:
package eventloop
type EventLoop struct {
nextFunc chan func()
curFunc chan func()
}
func NewEventLoop() *EventLoop {
el := &EventLoop{
// Adjust the capacities to taste
make(chan func(), 3),
make(chan func(), 3),
}
go eventLoop(el)
return el
}
func (el *EventLoop) NextTick(f func()) {
el.nextFunc <- f
}
func (el *EventLoop) CurrentTick(f func()) {
el.curFunc <- f
}
func (el *EventLoop) Quit() {
close(el.nextFunc)
}
func eventLoop(el *EventLoop) {
for {
f, ok := <-el.nextFunc
if !ok {
return
}
f()
drain: for {
select {
case f := <-el.curFunc:
f()
default:
break drain
}
}
}
}
根据您的使用,您可能需要添加一些同步以确保循环中的所有任务在程序退出之前完成。
关于mutex - 如何等待低延迟的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7547796/