英文:
Default case of select statement keeps executing
问题
相似问题:https://stackoverflow.com/questions/12615955/golang-goroute-with-select-doesnt-stop-unless-i-added-a-fmt-print
我正在使用Go编写一段代码,其中一个goroutine在套接字上接收和处理请求。为了停止当前goroutine的执行,我从其他goroutine向一个通道发送true
,而当前goroutine在select
语句中一直监听该通道。
但问题在于,即使在通道上发送了信号,default
块仍然会无限执行。而case
块永远不会执行。以下是我遇到问题的代码片段:
for {
select {
// 当在通道's.stopInbox'上接收到内容时,goroutine应该返回
case <-s.stopInbox:
fmt.Println("stopInbox")
return
// 在通道's.stopInbox'上接收到内容之前,一直接收和处理请求
default:
fmt.Println("default case")
msg, err := responder.Recv(0)
if err != nil {
fmt.Println("Error receiving message", err.Error())
break
}
envelope := msgToEnvelope(msg)
s.inbox <- &envelope
}
}
}
我已经搜索了这个问题,并找到了一些解决方案:
使用default语句,select将在没有从通道中读取内容时每次都运行default语句。因此,调度器将永远没有机会调度另一个goroutine。将
fmt.Print
语句放在其中可以让调度器调度其他goroutine。
根据建议,我尝试在default块中添加了一个打印语句,还尝试在default块中添加了一个休眠语句。但是都没有起作用。
有没有办法使这个工作?还有没有完全避免使用select
语句来实现预期效果的方法?
英文:
I am writing a code in go, where a goroutine keeps receiving and processing requests on a socket. To stop the execution of current goroutine, I send true
to a channel from some other goroutine, for which the current goroutine keeps listening in select
statement.
But the problem here is that even after sending signal on channel, default
block keeps executing forever. And case
block is never executed. Following is the code snippet I am having problem with.
for {
select{
//goroutine should return when something is received on channel 's.stopInbox'
case <-s.stopInbox:
fmt.Println("stopInbox")
return
//keep receiving and processing requests until anything is received on channel 's.stopInbox'
default:
fmt.Println("default case")
msg, err := responder.Recv(0)
if err != nil {
fmt.Println("Error receiving message", err.Error())
break
}
envelope := msgToEnvelope(msg)
s.inbox <- &envelope
}
}
I have searched for the problem and found solutions as
> With a default statement select will run the default statement every time there is nothing to read from the channels. And because of this, scheduler will never get a chance to schedule another goroutine. Putting the fmt.Print
statement in is allowing the scheduler to schedule other goroutines.
As per suggestion, I tried putting a print statement in default case, also I tried putting a sleep statement in default case. But nothing is working.
Is there any way to make this work? Also is it possible to achieve the intended by completely avoiding select
statement?
答案1
得分: 3
如果你在没有设置超时的情况下使用responder.Recv
,你的代码将永远阻塞在那里,而且你将无法进入default
部分。所以我猜你可以尝试设置一个超时时间
英文:
If you do responder.Recv
without a timeout, your code will block there forever and you won't get to the default
part. So I guess try setting a timeout
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论