WASI support in Go
原文在这里。
由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 发布于 2023年9月13日
Go 1.21添加了一个新的端口,通过新的GOOS值wasip1来定位WASI预览1系统调用API。该端口建立在Go 1.11引入的现有WebAssembly端口的基础上。
WebAssembly 是什么
WebAssembly(Wasm)是一种最初设计用于Web的二进制指令格式。它代表了一个标准,允许开发人员在Web浏览器中以接近本机速度直接运行高性能、低级别的代码。
Go首次在1.11版本中添加了对编译成Wasm的支持,通过js/wasm端口实现。这允许使用Go编译器编译的Go代码在Web浏览器中执行,但需要一个JavaScript执行环境。
随着Wasm的使用增加,除了在浏览器之外的用例也增多。许多云提供商现在提供服务,允许用户直接执行Wasm可执行文件,利用新的WebAssembly系统接口(WASI)系统调用API。
WebAssembly 系统接口
WASI定义了一个用于Wasm可执行文件的系统调用API,允许它们与系统资源进行交互,如文件系统、系统时钟、随机数据工具等等。WASI规范的最新版本被称为wasi_snapshot_preview1,从中我们派生出了GOOS名称wasip1。新版本的API正在开发中,未来在Go编译器中支持它们可能意味着添加一个新的GOOS。
WASI的创建使得许多Wasm运行时(宿主)能够围绕其标准化它们的系统调用API。一些Wasm/WASI宿主的示例包括Wasmtime、Wazero、WasmEdge、Wasmer和NodeJS。还有许多云提供商提供Wasm/WASI可执行文件的托管服务。
Go 中如何使用 WebAssembly
请确保已安装至少1.21版本的Go。对于此演示,我们将使用Wasmtime主机来执行我们的二进制文件。让我们从一个简单的 main.go 开始:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
使用如下命令进行编译:
$ GOOS=wasip1 GOARCH=wasm go build -o main.wasm main.go
这将会生成一个名为 main.wasm 的文件,我们可以使用 wasmtime 执行:
$ wasmtime main.wasm
Hello world!
这就是开始使用Wasm/WASI所需的全部!几乎所有Go的功能都可以在 wasip1 上正常工作。要了解有关WASI如何与Go一起工作的详细信息,请参阅提案。
测试 wasip1
构建和运行二进制文件很容易,但有时我们希望能够直接运行 go test,而无需手动构建和执行二进制文件。与 js/wasm 端口类似,Go安装中包含的标准库分发版本附带一个文件,使这个过程变得非常简单。在运行Go测试时,将 misc/wasm 目录添加到 PATH 中,它将使用你选择的Wasm主机来运行测试。这是通过 go test 在PATH中找到此文件时自动执行 misc/wasm/go_wasip1_wasm_exec 来实现的:
$ export PATH=$PATH:$(go env GOROOT)/misc/wasm
$ GOOS=wasip1 GOARCH=wasm go test ./...
这将使用 Wasmtime 运行 go test。可以使用环境变量 GOWASIRUNTIME 来控制所使用的Wasm主机。目前支持的变量值包括 wazero、wasmedge、wasmtime 和 wasmer。请注意,Go wasip1 二进制文件在所有主机上尚不能完美执行(参见#59907和#60097)。
也可以使用 go run来执行上面的程序:
$ GOOS=wasip1 GOARCH=wasm go run ./main.go
Hello world!
使用go:wasmimport在Go中包装Wasm函数
除了新的 wasip1/wasm 端口外,Go 1.21还引入了一个新的编译器指令:go:wasmimport。它指示编译器将对带有注释的函数的调用转换为对由主机模块名称和函数名称指定的函数的调用。这个新的编译器功能允许我们在Go中定义wasip1系统调用API,以支持新的端口,但它不限于在标准库中使用。
例如,wasip1系统调用API定义了 random_get 函数,并通过runtime包中定义的函数包装器暴露给Go标准库。它看起来像这样:
//go:wasmimport wasi_snapshot_preview1 random_get
//go:noescape
func random_get(buf unsafe.Pointer, bufLen size) errno
然后,将这个函数包装器包装在标准库中供使用的更人性化的函数中:
func getRandomData(r []byte) {
if random_get(unsafe.Pointer(&r[0]), size(len(r))) != 0 {
throw("random_get failed")
}
}
这样,用户可以使用字节切片调用 getRandomData ,并最终将其传递给主机定义的 random_get 函数。同样,用户可以为主机函数定义自己的包装器。
要了解如何在Go中包装Wasm函数的复杂性的更多细节,请参阅go:wasmimport提案。
局限性
虽然wasip1端口通过了所有标准库测试,但Wasm架构有一些显着的基本限制,可能会让用户感到惊讶。
Wasm是一个没有并行性的单线程架构。调度器仍然可以调度goroutine以并发运行,标准输入/输出/错误是非阻塞的,因此一个goroutine可以在另一个读取或写入时执行,但是任何主机函数调用(例如使用上面的示例请求随机数据)都会导致所有goroutine阻塞,直到主机函数调用返回。
wasip1 API中一个显着缺失的功能是完整的网络套接字实现。wasip1只定义了对已经打开的套接字进行操作的函数,这使得无法支持Go标准库的一些最流行的功能,如HTTP服务器。像Wasmer和WasmEdge这样的主机实现了wasip1 API的扩展,允许打开网络套接字。尽管Go编译器没有实现这些扩展,但存在第三方库,github.com/stealthrocket/net,使用go:wasmimport允许在支持的Wasm主机上使用net.Dial和net.Listen。这允许在使用此包时创建net/http服务器和其他与网络相关的功能。
Go中的Wasm的未来
wasip1/wasm 端口的添加只是我们希望引入Go的Wasm功能的开端。请密切关注问题跟踪器,了解有关将Go函数导出到Wasm(go:wasmexport)、32位端口和未来WASI API兼容性的提案。
参与其中
如果你正在尝试并希望为Wasm和Go做出贡献,请参与其中!Go问题跟踪器跟踪所有正在进行的工作,Gophers Slack上的 #webassembly 频道是讨论Go和WebAssembly的好地方。我们期待听到你的声音!
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
WASI support in Go的更多相关文章
- Android注解使用之使用Support Annotations注解优化代码
前言: 前面学习总结了Java注解的使用,博客地址详见Java学习之注解Annotation实现原理,从本质上了解到什么注解,以及注解怎么使用?不要看见使用注解就想到反射会影响性能之类,今天我们就来学 ...
- Android Support 包知识
Android Support Library包是一组代码库, 它提供了向后版本的framework API的兼容, 这些代码库实现的效果和只能在指定版本中使用的API一样好. 每个Support L ...
- 解决Native atomics support not found问题
今天用arm-none-linux-gnueabi交叉编译libmysqclient.so,出现Native atomics support not found问题 进入mysql-connector ...
- 使用 CoordinatorLayout 出错 inflating class android.support.design.widget.CoordinatorLayout
ava.lang.RuntimeException: Unable to start activity ComponentInfo{com.czr.ianpu/com.czr.ianpu.MainAc ...
- Your app declares support for audio in the UIBackgroundModes key in your Info.plist 错误
提交AppStore时候被拒绝 拒绝原因:Your app declares support for audio in the UIBackgroundModes key in your Info.p ...
- 在布局中使用android.support.v4.app.Fragment的注意事项
1.Activity必须继承android.support.v4.app.FragmentActivity 2.fragment标签的name属性必须是完全限定包名,如下: <LinearLay ...
- 启动项目的时候报驱动错误: not support oracle driver 1.0
问题:今天在使用pom导入oracle14的包时候发现怎么都下载不过来.网上查了一下发现是因为Oracle驱动需要官方授权,所以在pom.xml文件直接配置,无法下载成功. 解决方法就是下载oracl ...
- Android Support Library
title: Android Support Library tags: Support Library,支持库 grammar_cjkRuby: true --- DATE: 2016-5-13. ...
- How To Install Proxmox Nested on VMware ESXi (Full Support OpenVZ & KVM)
https://imanudin.net/2015/03/04/how-to-install-proxmox-nested-on-vmware-esxi-full-support-openvz-kvm ...
- CAST function should support INT synonym for SIGNED. i.e. CAST(y AS INT)
Login / Register Developer Zone Bugs Home Report a bug Statistics Advanced search Saved searches T ...
随机推荐
- R 语言柱状图示例笔记
由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文章中链接. 一.基础柱状图 1. barplot 命令 基于barplot基础柱状图颜色.方向及分组的绘 ...
- spring cloud gateway网关(一)之网关路由
1.gateway相关介绍 在微服务架构中,系统往往由多个微服务组成,而这些服务可能部署在不同机房.不同地区.不同域名下.这种情况下,客户端(例如浏览器.手机.软件工具等)想要直接请求这些服务,就需要 ...
- 搭建私人GPT及域名配置
前几天在掘金看到一个搭建私人ChatGPT的教程,看起来并不难. 我也有OpenAI的API Key,然后前阵子我看到我的账号余额还有很多,我的api key其实就一个机器人在用,没用多少. 还有,就 ...
- Nashorn引擎导致metaspace oom
从报错内容很清楚是Metaspace区域oom了 大部分情况下,程序运行中不会出现过多的类加载数量的变动,先导入dump文件检查是否有异常的classLoader或者有异常动态生成的cla ...
- 行行AI人才直播第3期:浙江大学周鑫博士《空中机器人复杂环境高效自主导航—从单机到集群》
行行AI人才是博客园和顺顺智慧共同运营的AI行业人才全生命周期服务平台. 空中飞行的无人车.无人机集群是科幻电影的常客,也往往是未来科技的一大代表.在电影<星球大战:西斯的复仇>(2005 ...
- SQL Sever 各版本的适用环境
很多用visual studio做开发的朋友经常会用到sqlserver数据库,但是往往在选择的时候就不知道该使用哪个版本了,今天就给大家分享一下sqlserver各个版本之间的区别,以及各个版本之间 ...
- P3755 [CQOI2017]老C的任务题解
如果询问 \(x_1, y_1, x_2, y_2\), 那么询问 \((x_2, y_2)\), \((x_2, y_1 - 1)\), \((x_1 - 1, y_2)\) \((x_1 - 1, ...
- 一文了解io.ReadAtLeast函数
1. 引言 io.ReadAtLeast 函数是Go标准库提供的一个非常好用的函数,能够指定从数据源最少读取到的字节数.本文我们将从io.ReadAtLeast 函数的基本定义出发,讲述其基本使用和实 ...
- 《最新出炉》系列入门篇-Python+Playwright自动化测试-9-页面(page)
1.简介 通过前边的讲解和学习,细心认真地小伙伴或者童鞋们可能发现在Playwright中,没有Element这个概念,只有Page的概念,Page不仅仅指的是某个页面,例如页面间的跳转等,还包含了所 ...
- Mybatis(映射器 mappers)
MapperRegistry:注册绑定我们的Mapper文件 方式一: <!--每一个Mapper.XML都需要在Mybatis核心配置文件中注册--> <mappers> & ...