Golang中单二进制文件还是多二进制文件的优劣探讨
Golang中单二进制文件还是多二进制文件的优劣探讨 大家好,
我刚开始学习 Golang(或者叫 GoLand 😉),想听听更有经验的人士关于如何进行的建议。
事情是这样的,我有五个用 C 语言编写的应用程序。我想把这些应用程序移植到 Go 语言,但在闪存(硬盘)空间方面遇到了一些问题。
我的问题是……我应该制作五个 Go 应用程序,并将它们作为五个独立的操作系统进程运行吗?这样每个 Go 二进制文件都将拥有自己的“完整的 Go 底层机器”。还是应该只制作一个 Go 应用程序,并在 Go 内部让它们全部并发运行,这样一体化的 Go 应用程序最终将消耗更少的闪存,因为“完整的 Go 底层机器”将被共享?
提前感谢。
[]s
更多关于Golang中单二进制文件还是多二进制文件的优劣探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
当然,你可以像git那样创建一个包含多个子命令的命令。git add、git commit等等。
或者使用硬链接/软链接并通过 os.Args[0] 进行分发
这五个程序是相关的吗?还是它们做的是完全不同的事情?
如果可执行文件的大小很重要,请坚持使用经过大小优化的C语言并动态链接共享库。
另外不要忘记使用 strip。
嗯,今天在C语言中它们有些关联,但并非完全如此……这就是为什么它们是五个独立的程序,但我的问题更多是针对我有限的闪存容量所面临的困境。
实际上,我认为我之前没有清楚地表达自己的想法。经过几天的研究,我得出了一个结论。
请告诉我以下想法是否合理:
每个 Go 应用程序都包含"运行时代码",这些代码最终会被包含在生成的二进制文件中。因此这会影响到二进制文件的最终大小。如果我有五个 Go 二进制文件,它们都会占用我在闪存(硬盘)上的空间。所以如果只从闪存消耗的角度考虑,最好只使用一个包含五个功能的二进制文件。从数学上来看是这样的:
假设每个功能占用 1MB,Go 运行时代码占用 2MB,那么:
五个二进制文件将占用:(2MB+1MB)5 = 15MB 一个包含五个功能的二进制文件:2MB + (1MB5) = 7MB
你觉得这个理解合理吗?
谢谢
在Golang中,选择单二进制文件还是多二进制文件主要取决于你的具体需求和约束条件。以下是对两种方案的详细分析:
多二进制文件方案
- 优点:每个应用程序独立运行,进程隔离性强,一个应用崩溃不会影响其他应用;部署和更新灵活,可以单独升级某个应用。
- 缺点:每个二进制文件都包含完整的Go运行时和依赖库,导致总存储空间占用较高;内存使用可能更多,因为每个进程都有自己的运行时开销。
示例代码结构(假设有五个独立应用):
// 应用1: app1/main.go
package main
import "fmt"
func main() {
fmt.Println("Running App1")
// 应用1的业务逻辑
}
// 应用2: app2/main.go
package main
import "fmt"
func main() {
fmt.Println("Running App2")
// 应用2的业务逻辑
}
// 其他应用类似...
编译命令:go build -o app1 app1/main.go,依此类推,生成五个独立二进制文件。
单二进制文件方案
- 优点:显著减少存储空间占用,因为Go运行时和公共依赖只被包含一次;内存使用可能更高效,通过goroutine共享资源;统一部署和管理。
- 缺点:所有应用运行在同一进程内,一个应用的问题(如panic)可能影响整体稳定性;代码耦合度较高,需谨慎设计并发和错误处理。
示例代码结构(单二进制文件,使用goroutine并发运行多个应用):
package main
import (
"context"
"fmt"
"sync"
"time"
)
func app1(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Println("App1 stopped")
return
default:
fmt.Println("App1 running")
time.Sleep(2 * time.Second)
}
}
}
func app2(ctx context.Context, wg *sync.WaitGroup) {
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Println("App2 stopped")
return
default:
fmt.Println("App2 running")
time.Sleep(3 * time.Second)
}
}
}
// 定义其他应用函数...
func main() {
ctx, cancel := context.WithCancel(context.Background())
var wg sync.WaitGroup
// 启动所有应用作为goroutine
wg.Add(5)
go app1(ctx, &wg)
go app2(ctx, &wg)
// 启动app3, app4, app5...
// 模拟运行一段时间后停止
time.Sleep(10 * time.Second)
cancel()
wg.Wait()
fmt.Println("All apps stopped")
}
编译命令:go build -o single_app main.go,生成一个二进制文件。
总结
- 如果闪存空间是主要瓶颈,且应用间耦合度低、能容忍单点故障风险,推荐单二进制文件方案。
- 如果需要高隔离性、独立部署能力,且存储空间充足,多二进制文件更合适。
在实际移植时,评估应用间的交互和资源需求,选择最适合你场景的方案。

