【发布时间】:2020-11-24 08:55:24
【问题描述】:
我有一个goroutine,我们称之为goProcessor,它处理来自其他goroutine的请求。
goProcessor 一次只能处理一个请求。如果一个请求,我们称之为 req2,在 goProcessor 仍在处理之前的 req1 请求时进来,req2 必须被丢弃并且只会丢失。
我已经使用无缓冲通道和select 语句实现了这样的逻辑,但我不确定是否有更简单更优雅的方式来完成我想要的。我的解决方案的一个简单示例是这样的
var c = make(chan string)
func main() {
goRequest := func(request string, delay int) {
time.Sleep(time.Duration(delay) * time.Second)
fmt.Printf("Here I am request %v\n", request)
select {
case c <- request:
fmt.Printf("%v sent\n", request)
default:
fmt.Printf("%v discarded\n", request)
}
}
goProcessor := func() {
for {
msg := <-c
fmt.Println("received", msg)
time.Sleep(3 * time.Second)
fmt.Println("processed", msg)
}
}
go goRequest("First req", 1)
go goRequest("Second req", 2)
go goRequest("Third req", 5)
go goProcessor()
time.Sleep(10 * time.Second)
fmt.Println("Main has finished")
}
【问题讨论】:
-
@icza 谢谢。我正在想象一个使用某种互斥锁的解决方案,当有人在已经锁定时尝试锁定它时会出现一些错误。但找不到任何东西,所以我恢复到频道。
-
将我的 cmets 转换为答案。
标签: go concurrency channel goroutine