gpt4 book ai didi

go - 事件处理中的死锁

转载 作者:IT王子 更新时间:2023-10-29 00:43:52 26 4
gpt4 key购买 nike

所以我有一个用于事件处理的 channel ,主服务器 goroutine 在这个 channel 上选择并在收到的每个事件上调用事件处理程序:

evtCh := make(chan Event)
// server loop:
for !quit {
select {
case e := <- evtCh:
handleEvent(e)
break
case quit := <-quitCh:
//finish
}

// for send a new event to processing
func addEvent(e Event) {
evtCh <- e
}

handleEvent 将调用事件类型的已注册处理程序。我有 func registerEventHandler(typ EventType, func(Event)) 来处理寄存器。该程序将支持用户编写扩展,这意味着他们可以注册自己的处理程序来处理事件。

现在问题出现在用户的事件处理程序中,他们可能会通过调用 addEvent 向服务器发送新事件,这将导致服务器挂起,因为事件处理程序本身是在服务器的主循环(在 for 循环中)。

如何优雅地处理这种情况?按 slice 建模的队列是个好主意吗?

最佳答案

this will cause the server to hang since the event handler itself is called in the context of the server's main loop

主循环不应该在调用 handleEvent 时阻塞,避免这种情况的最常见方法是使用 worker goroutines 池。这是一个快速的未经测试示例:

type Worker struct {
id int
ch chan Event
quit chan bool
}

func (w *Worker) start {
for {
select {
case e := <- w.ch:
fmt.Printf("Worker %d called\n", w.id)
//handle event
break;
case <- w.quit:
return
}
}
}


ch := make(chan Event, 100)
quit := make(chan bool, 0)

// Start workers
for i:=0; i<10; i++{
worker := &Worker{i,ch,quit}
go worker.start()
}

//
func addEvent (e Event) {
ch <- e
}

完成后,只需close(quit) 即可杀死所有 worker。

编辑:来自以下评论:

what is the main loop looks like in this case?

视情况而定。如果您有固定数量的事件,您可以使用 WaitGroup ,像这样:

type Worker struct {
id int
ch chan Event
quit chan bool
wg *sync.WaitGroup
}

func (w *Worker) start {
for {
select {
case e := <- w.ch:
//handle event
wg.Done()

break;
case <- w.quit:
return
}
}
}

func main() {
ch := make(chan Event, 100)
quit := make(chan bool, 0)

numberOfEvents := 100

wg := &sync.WaitGroup{}
wg.Add(numberOfEvents)

// start workers
for i:=0; i<10; i++{
worker := &Worker{i,ch,quit,wg}
go worker.start()
}


wg.Wait() // Blocks until all events are handled
}

如果事先不知道事件的数量,你可以在退出 channel 上阻塞:

<- quit

一旦另一个 goroutine 关闭 channel ,您的程序也将终止。

关于go - 事件处理中的死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36982347/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com