[读书笔记] go 语言如何处理系统调用
上一篇博客主要是讲如何避免在高并发下使用太多系统线程或进程,但如果仅仅是减少了线程数,CPU利用率本身没有上来,那么系统的容量很低,那么仍然无法达到高并发的目的。
通常情况下,我们会设置线程数等于CPU数,充分利用CPU就等价于如何让线程一直工作,避免把时间浪费在等待系统调用返回上,从而提高系统容量。
很多 linux 平台下的异步框架都基于 epoll 来设计,但 epoll 本身只支持 fd, 也就是说能很好的支持文件IO以及socket, 但对于其他系统调用则无法处理,在调用时仍然会造成堵塞,比如 creat, unlink等等。在大部分情况下,能对文件IO和socket进行异步处理已经能满足我们的需求,比如 libevent, Java 的 NIO 都只提供了这些支持。
node.js 支持得更多一些,具体可以参考他的 fs 模块 ,对大量的系统调用同时提供了同步调用和异步调用的接口。
go 语言在编程的时候无需开发者对系统调用做特殊处理,我相信他在内部做了一些处理来支持他的高并发特性,但毕竟要眼见为实。
go 语言与系统调用的模块放在 syscall package,并在上面封装出了 "os", "time", "net" 等模块,并且建议直接使用后面的模块,单从 syscall 里边函数的接口来看,看不到任何异步非阻塞的迹象,只能从源代码的角度来分析。
syscall package 的源码位于 src/pkg/syscall/syscall_linux.go 等文件,不过里边的函数都是简单地对更底层函数的一个包装,比如
//sys open(path string, mode int, perm uint32) (fd int, errno int)
func Open(path string, mode int, perm uint32) (fd int, errno int) {
return open(path, mode|O_LARGEFILE, perm)
}
真正按异步方式的代码位于 src/pkg/syscall/zsyscall_linux_amd64.go 这样的文件里,这个文件是由上面的文件编译而成的,范例如下
func open(path string, mode int, perm uint32) (fd int, errno int) {
r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(StringBytePtr(path))), uintptr(mode), uintptr(perm))
fd = int(r0)
errno = int(e1)
return
}
Syscall 的定义位于 src/pkg/syscall/asm_linux_amd64.s, 是用汇编写成的,不过我不懂汇编(泪)
TEXT ·Syscall(SB),7,$0
CALL runtime·entersyscall(SB)
MOVQ 16(SP), DI
MOVQ 24(SP), SI
MOVQ 32(SP), DX
MOVQ $0, R10
MOVQ $0, R8
MOVQ $0, R9
MOVQ 8(SP), AX // syscall entry
SYSCALL
CMPQ AX, $0xfffffffffffff001
JLS ok
MOVQ $-1, 40(SP) // r1
MOVQ $0, 48(SP) // r2
NEGQ AX
MOVQ AX, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
ok:
MOVQ AX, 40(SP) // r1
MOVQ DX, 48(SP) // r2
MOVQ $0, 56(SP) // errno
CALL runtime·exitsyscall(SB)
RET
其中 runtime·entersyscall 和 runtime·exitsyscall 位于 src/pkg/runtime/proc.c
分析不下去了,不过能确认的是, go 语言确实做了什么,避免了系统调用堵塞线程,保证了程序能充分使用 CPU。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析