我对在goroutine中使用SMTP发现的一些奇怪行为感到困惑。
尝试使用以下代码发送电子邮件时,我的SendMail函数启动(我可以看到日志消息),但永远不会完成。它只是挂起。
Intent dialogIntent = new Intent(applicationCotext, DialogActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
applicationCotext.startActivity(dialogIntent);
但是,当我向SendMail添加另一个电话时 - 两个电子邮件都已成功发送。
func main() {
go SendEmail("TEST")
for {}
}
有人可以解释发生了什么吗?
注意,这是一个非常简化的计划任务版本,因此是while循环
发送电子邮件的代码:
func main() {
go SendEmail("TEST")
SendEmail("TEST")
for {}
}
谢谢!
答案 0 :(得分:1)
您应该将for{}
替换为select{}
。永远不要创建一个空的for{}
。
for{}
创建一个永远旋转的循环,但由于循环中没有函数调用(或更准确地堆栈检查和/或分配),调度程序将永远无法对主goroutine进行计划,这反过来又会阻止你的其他goroutine被安排。 (这也可能会占用整个CPU,因为你忙于循环操作系统线程)
最后请参阅我关于GOMAXPROCS的说明。
在SendEmail("TEST")
运行时获得机会(或更确切地说,多次机会)之后立即调用go SendEmail("TEST")
,以便在进入for{}
循环之前安排其他goroutine运行。< / p>
使用空的select(select{}
)代替,主goroutine将无限期地等待而不消耗任何CPU,而是直接产生调度程序。
关于GOMAXPROCS
如果您的GOMAXPROCS为1(在Go 1.5之前默认),您将只有一个OS线程(至少用于运行goroutines),如果您有忙循环,这将阻止任何其他goroutine运行。如果你有GOMAXPROCS&gt; 1运行时仍然可以安排其他goroutine,因为有多个线程用于运行goroutine,但你不应该依赖它。相反,您应该删除任何繁忙的循环。