You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何未调用checkLink的两个Go程序行为有差异?编译程序被删原因?

问题原因拆解

1. 两个程序行为差别的核心:init函数在搞事情

你说没调用checkLink,但Go程序会自动执行所有包级的init函数,俩程序的差异肯定出在这:

  • Program 1:init里启动的goroutine大概率在操作未正确初始化的通道或同步锁,导致所有goroutine(包括main)都堵死了。Go运行时能检测到这种“所有goroutine都休眠”的情况,直接抛出all goroutines are asleep - deadlock!然后终止程序。
  • Program 2:init里的goroutine可能是在等一个永远不会来的信号(比如空通道的接收操作),但main goroutine没退出(比如main函数是空的,或者也在无限等待)。Go的死锁检测只在所有goroutine都阻塞时触发,要是main还在跑(哪怕是空循环),就不会报错,程序就一直挂着。

2. go build生成的可执行文件被删的原因(macOS+ZSH)

这和Go本身没关系,大概率是两种情况:

  • 你Program 2的代码里写了主动删除自身的逻辑(比如用os.Remove删除当前可执行文件的路径)。
  • ZSH的配置或者安全软件(比如Mac的隐私保护、第三方杀毒工具)把这个无输出的挂起进程当成异常,直接终止进程还删除了可执行文件。可以换bash环境试试,或者暂时关闭安全软件验证。

3. Go Tour里Program 2和Program 1行为一致的原因

Go Tour是沙箱化运行环境,会给程序设置超时时间,而且死锁检测逻辑和本地go run对齐。当Program 2的goroutine堵死之后,沙箱要么触发超时,要么检测到死锁,直接终止程序,所以表现和Program 1一致。

验证小技巧

  • 检查两个程序的init函数和包级变量初始化代码,找启动goroutine、操作通道的差异。
  • 给Program 2的可执行文件先备份一份,运行后看备份是否还存在,排除代码主动删除的可能。
  • 在Program 2的main函数里加一行fmt.Println("main done"),看能不能正常输出,判断main goroutine有没有正常退出。

内容的提问来源于stack exchange,提问作者Sandeep Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:35:08