GO程序无法执行

GO程序无法执行,第1张

描述: 在运行以下没有语法错误的go文件的时候,出现以下

fork/exec C:\Users\KyoDante\AppData\Local\Temp\go-build269385730\b001\exe\gram.exe: This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher.

提示程序不兼容系统的版本。但是使用go env查看GOARCH=amd64,按理说不会出现这种情况。

原因: 使用WeGame打开DNF之后,会出现这种情况。而在关闭游戏和WeGame等程序之后,运行时仍然出现这个问题,考虑是由于打开DNF之后导致的问题。

解决: 重启后可以解决。情况就是:打游戏和学习不要同时进行。

你有在 Go 程序中使用 syscall.Mmap 吗?答案很可能是肯定的,只是你不知道而已。因为你的程序直接或间接的依赖包会使用 syscall.Mmap,毕竟众所周知的:mmap 要比常规的 I/O *** 作快。我们现在来看一下到底是不是这样。

mmap 是一个系统调用,将文件内容直接映射到内存地址空间。mmap 之后,你就可以像访问内存一样对文件内容进行读写。这样就不需要使用比较重的系统调用去对文件内容进行读写了。

使用系统调用 *** 作文件,进程会在内核态和用户态之间频繁切换,而且数据还要在用户态和内核态之间来回拷贝。而 mmap 后,整个数据的读写都在用户态完成,不会进入内核态,同时也少了一次数据拷贝。是不是觉得很完美?其实不是的。

程序访问 mmap 返回的内存地址空间会发生什么?有两种场景:

你可能会说,那正常的使用 read/write 访问冷数据,也会有同样的问题;也会触发缺页中断,唯一不同的是把内存访问换成了一个系统调用。

的确是这样,但是让我们来看一下 Go 的运行时机制。

Go 的 goroutine 是运行在 OS threads( *** 作系统线程)之上的。最多可以有 GOMAXPROCS 个 goroutine 并行 的运行在 OS thread 上。其他就绪的 goroutine 会一直等待,直到运行中的 goroutine 发生了阻塞、出让、或者系统调用。goroutine 会因为 I/O、channel、mutex 而阻塞,会因为函数调用、内存分配、调用 runtime.Gosched 而出让。 Goroutine 并不会因为缺页中断而阻塞!

再强调一次,goroutine 不会因为缺页中断而发生阻塞或出让,因为它对 Go 运行时是不可见的。 那当一个 goroutine 通过 mmap 访问到冷数据时,会发生什么呢?它会让你的程序卡在那里很长很长时间。在这期间,它还是会持续占用你的 OS thread,所以其他就绪的 goroutine 因为受到 GOMAXPROCS 的限制,只能排队。这就导致 CPU 的利用率很低。如果 GOMAXPROCS 个 goroutine 同时访问 mmap 文件的冷数据,会发生什么?整个程序会彻底地 Hang 住,直到 OS 完成了这些 goroutine 触发的缺页中断。

监控请求延迟和 CPU 利用率:

这些程序在程序访问 page cache 中的数据时,是没有任何问题的。page cache 的大小受内存大小限制。所以这些程序只有在被 mmap 的文件很大时(超出内存大小),才会出现卡住的现象。在低负载场景,或者存储设备较快时(比如 SSD),不太容易注意到程序出现卡顿。

当 mmap 文件小于内存空间时,以下场景也会出现卡顿:

尽量避免在 Go 程序中使用 mmap,因为它可能让你的程序 Hang 住。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/10990054.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-12
下一篇2023-05-12

发表评论

登录后才能评论

评论列表(0条)

    保存