Go语言在网络编程方面有许多优势。其卓越的并发模型和简洁的语法使其成为构建高效网络应用的理想选择。首先,Go语言内置的协程(goroutine)和通道(channel)机制使并发编程变得简单,允许在程序中轻松地创建大量的并发任务,而无需过多的线程管理和锁。这导致了更高效的资源利用和更快的响应时间。
其次,Go标准库中丰富的网络包(net包)为网络编程提供了强大的支持,涵盖了TCP、UDP、HTTP等协议的实现,使开发者能够更轻松地构建网络应用。
此外,Go语言具有编译型语言的优势,能够生成高效的机器码,使得网络应用在性能上表现出色。同时,其强大的错误处理机制和自带的测试框架有助于构建稳定和可维护的网络应用。
综上所述,Go语言在网络编程方面的并发支持、丰富的网络库和性能表现,使其成为构建高性能、可靠网络应用的优秀选择。
一、运行Golang的hello程序
以下是一个简单的Go语言Hello World程序示例:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
可以将上述代码保存为一个 .go
后缀的文件,例如 hello.go
,然后通过终端进入该文件所在的目录,使用以下命令编译并运行程序:
go run hello.go
运行命令后,你会在终端看到输出:
Hello, World!
由于Golang官网上下载的Golang包在开发板上无法运行,所以考虑以交叉编译的方式来尝试。
二、
在X86平台的Linux上,按常规的Go语言交叉编译方式,只需要在命令行运行以下命令即可
CGO_ENABLED=0 GOARCH=riscv64 go build -ldflags="-s -w" -o helloG hello.go
上传到开发板上测试
错误信息如下:
[root@milkv]~# ./helloG
runtime: epollcreate failed with 38
fatal error: runtime: netpollinit failed
goroutine 1 [running, locked to thread]:
runtime.throw({0x3b7f18?, 0xaf350?})
/home/walker/.bin/go/src/runtime/panic.go:1077 +0x44 fp=0x3f90072ba8 sp=0x3f90072b80 pc=0x463a4runtime.netpollinit()
/home/walker/.bin/go/src/runtime/netpoll_epoll.go:28 +0x1b4 fp=0x3f90072c18 sp=0x3f90072ba8 pc=0x425b4
runtime.netpollGenericInit()
/home/walker/.bin/go/src/runtime/netpoll.go:216 +0x64 fp=0x3f90072c28 sp=0x3f90072c18 pc=0x41a8c
internal/poll.runtime_pollServerInit()
/home/walker/.bin/go/src/runtime/netpoll.go:208 +0x20 fp=0x3f90072c30 sp=0x3f90072c28 pc=0x72558
sync.(*Once).doSlow(0xc9d08?, 0xc9c4c?)
/home/walker/.bin/go/src/sync/once.go:74 +0xf4 fp=0x3f90072c80 sp=0x3f90072c30 pc=0x8f024
sync.(*Once).Do(...)
/home/walker/.bin/go/src/sync/once.go:65
internal/poll.(*pollDesc).init(0x3f900601a0, 0x3f90060180)
/home/walker/.bin/go/src/internal/poll/fd_poll_runtime.go:39 +0x64 fp=0x3f90072c98 sp=0x3f90072c80 pc=0xc3d4c
internal/poll.(*FD).Init(0x3f90060180, {0x3acc3b?, 0x3f9000c0f0?}, 0xc?)
/home/walker/.bin/go/src/internal/poll/fd_unix.go:65 +0xa0 fp=0x3f90072cb0 sp=0x3f90072c98 pc=0xc46a0
os.newFile(0x3, {0x3f9000c0f0, 0xc}, 0x1)
/home/walker/.bin/go/src/os/file_unix.go:233 +0x1a0 fp=0x3f90072ce8 sp=0x3f90072cb0 pc=0xc9d68
os.openFileNolog({0x3f9000c0f0, 0xc}, 0x0, 0x0)
/home/walker/.bin/go/src/os/file_unix.go:301 +0x1b0 fp=0x3f90072d28 sp=0x3f90072ce8 pc=0xc9f80
os.OpenFile({0x3f9000c0f0, 0xc}, 0x0, 0x0?)
/home/walker/.bin/go/src/os/file.go:334 +0x64 fp=0x3f90072d58 sp=0x3f90072d28 pc=0xc902c
os.Open(...)
/home/walker/.bin/go/src/os/file.go:314
google.golang.org/protobuf/internal/detrand.binaryHash()
/home/walker/go/pkg/mod/google.golang.org/protobuf@v1.30.0/internal/detrand/rand.go:46 +0x48 fp=0x3f90072e18 sp=0x3f90072d58 pc=0x2c5d30
google.golang.org/protobuf/internal/detrand.init()
/home/walker/go/pkg/mod/google.golang.org/protobuf@v1.30.0/internal/detrand/rand.go:38 +0x20 fp=0x3f90072e20 sp=0x3f90072e18 pc=0x2c5fd0
runtime.doInit1(0x661590)
/home/walker/.bin/go/src/runtime/proc.go:6740 +0xdc fp=0x3f90072f48 sp=0x3f90072e20 pc=0x56a9c
runtime.doInit(...)
/home/walker/.bin/go/src/runtime/proc.go:6707
runtime.main()
/home/walker/.bin/go/src/runtime/proc.go:249 +0x3ac fp=0x3f90072fd8 sp=0x3f90072f48 pc=0x48d6c
runtime.goexit()
/home/walker/.bin/go/src/runtime/asm_riscv64.s:512 +0x4 fp=0x3f90072fd8 sp=0x3f90072fd8 pc=0x7749c
goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/home/walker/.bin/go/src/runtime/proc.go:398 +0x10c fp=0x3f9003efa8 sp=0x3f9003ef90 pc=0x49134
runtime.goparkunlock(...)
/home/walker/.bin/go/src/runtime/proc.go:404
runtime.forcegchelper()
/home/walker/.bin/go/src/runtime/proc.go:322 +0xd4 fp=0x3f9003efd8 sp=0x3f9003efa8 pc=0x48f9c
runtime.goexit()
/home/walker/.bin/go/src/runtime/asm_riscv64.s:512 +0x4 fp=0x3f9003efd8 sp=0x3f9003efd8 pc=0x7749c
created by runtime.init.5 in goroutine 1
/home/walker/.bin/go/src/runtime/proc.go:310 +0x28
goroutine 3 [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
/home/walker/.bin/go/src/runtime/proc.go:398 +0x10c fp=0x3f9003f780 sp=0x3f9003f768 pc=0x49134
runtime.goparkunlock(...)
/home/walker/.bin/go/src/runtime/proc.go:404
runtime.bgsweep(0x0?)
/home/walker/.bin/go/src/runtime/mgcsweep.go:280 +0xb4 fp=0x3f9003f7c8 sp=0x3f9003f780 pc=0x34b94
runtime.gcenable.func1()
/home/walker/.bin/go/src/runtime/mgc.go:200 +0x2c fp=0x3f9003f7d8 sp=0x3f9003f7c8 pc=0x292a4
runtime.goexit()
/home/walker/.bin/go/src/runtime/asm_riscv64.s:512 +0x4 fp=0x3f9003f7d8 sp=0x3f9003f7d8 pc=0x7749c
created by runtime.gcenable in goroutine 1
/home/walker/.bin/go/src/runtime/mgc.go:200 +0x70
goroutine 4 [GC scavenge wait]:
runtime.gopark(0x3f9005c000?, 0x43a150?, 0x0?, 0x0?, 0x3f90000d00?)
/home/walker/.bin/go/src/runtime/proc.go:398 +0x10c fp=0x3f9003ff80 sp=0x3f9003ff68 pc=0x49134
runtime.goparkunlock(...)
/home/walker/.bin/go/src/runtime/proc.go:404
runtime.(*scavengerState).park(0x6b1260)
/home/walker/.bin/go/src/runtime/mgcscavenge.go:425 +0x68 fp=0x3f9003ffa8 sp=0x3f9003ff80 pc=0x322b8
runtime.bgscavenge(0x0?)
/home/walker/.bin/go/src/runtime/mgcscavenge.go:653 +0x50 fp=0x3f9003ffc8 sp=0x3f9003ffa8 pc=0x32830
runtime.gcenable.func2()
/home/walker/.bin/go/src/runtime/mgc.go:201 +0x2c fp=0x3f9003ffd8 sp=0x3f9003ffc8 pc=0x29244
runtime.goexit()
/home/walker/.bin/go/src/runtime/asm_riscv64.s:512 +0x4 fp=0x3f9003ffd8 sp=0x3f9003ffd8 pc=0x7749c
created by runtime.gcenable in goroutine 1
/home/walker/.bin/go/src/runtime/mgc.go:201 +0xb0
goroutine 5 [finalizer wait]:
runtime.gopark(0x73740?, 0x0?, 0x0?, 0x0?, 0x0?)
/home/walker/.bin/go/src/runtime/proc.go:398 +0x10c fp=0x3f9003e5a8 sp=0x3f9003e590 pc=0x49134
runtime.runfinq()
/home/walker/.bin/go/src/runtime/mfinal.go:193 +0x108 fp=0x3f9003e7d8 sp=0x3f9003e5a8 pc=0x28398
runtime.goexit()
/home/walker/.bin/go/src/runtime/asm_riscv64.s:512 +0x4 fp=0x3f9003e7d8 sp=0x3f9003e7d8 pc=0x7749c
created by runtime.createfing in goroutine 1
/home/walker/.bin/go/src/runtime/mfinal.go:163 +0x64
三、在riscv64环境下的Go环境编译
由于VF2开发板是riscv64架构的,所以不需要添加GOARCH环境配置
CGO_ENABLED=0 go build -ldflags="-s -w" -o helloRG hello.go
然后上传到开发板上运行
[root@milkv]~
Hello world
是可以正常运行的。
有点奇怪的经历,测试过在X86平台交叉编译GO程序(helloworld和web点灯),放到arm平台上运行,可以正常运行。但是riscv64平台上就跑不了。