WASI support in Go

来源:https://www.cnblogs.com/lianshuiwuyi/archive/2023/09/15/17705889.html
-Advertisement-
Play Games

原文在這裡。 由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 發佈於 2023年9月13日 Go 1.21添加了一個新的埠,通過新的GOOS值wasip1來定位W ...


原文在這裡

由 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宿主的示例包括WasmtimeWazeroWasmEdgeWasmerNodeJS。還有許多雲提供商提供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主機。目前支持的變數值包括 wazerowasmedgewasmtimewasmer。請註意,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: 戀水無意



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄前言一、監聽UITextField 內容變化1. 代理2. 通知3. 目標動作事件二、監聽UITextView文本內容高度變化三、cell中的文本框,在reloadData or reloadRow後失去焦點四、手機號碼、銀行卡號格式化 前言 本文總結了在使用 UITextField & UIT ...
  • 最近在寫項目的一些公共組件(一些選擇器),很多個地方都需要用,所以在main.js全局聲明瞭,但發現子頁面調用還是有挺多的地方需寫。 例如,要在template實例化組件,並用ref綁定,然後在js里的methods里寫方法。 main.js 聲明全局組件 第一種方案 一開始想到的是用ref綁定組件 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 背景 應用背景:vite搭建的vue3項目 需求背景:功能都涉及了支付業務,故需要和外部支付系統對接 外部支付系統:聚合支付、微信小程式支付、微信H5支付 目錄 讀完本文,你將會對以下幾個坑點有所瞭解: 對接第三方服務商過程踩坑 對接小程 ...
  • 分享的 HTML 與上圖內容一樣,需要修改的小伙伴可以自行修改內容。 <style><!-- @import url("https://fonts.googleapis.com/css?family=Share+Tech+Mono|Montserrat:700"); * { margin: 0; p ...
  • 系統設計之緩存五種策略 當我們在架構中引入緩存時,緩存和資料庫之間的同步就變得不可避免。 讓我們看看如何保持數據同步的五種常見策略。 1)閱讀策略: 緩存在一邊 通讀2)寫策略:寫周圍 回信 寫通緩存策略經常組合使用。例如,write-around 通常與 cache-aside 一起使用,以確保緩 ...
  • 一、背景介紹 我們團隊一直在持續推進業務系統的體系化治理工作,在這個過程中我們沉澱了自己的DDD腳手架項目。腳手架項目是體系化治理過程中比較重要的一環,它的作用有兩點: 可以對新建的項目進行統一的規範 對於指導老項目進行DDD的改造提供指導 本文主要是梳理和總結了DDD腳手架使用中的編碼規範以及遇到 ...
  • 在設備維修保養管理中,及時通知相關人員是確保設備得到及時維護的關鍵。API介面提供了一個方便的方式來自動發送維修保養通知,以確保工作流程的順利進行。本文將詳細介紹如何使用成熟的API介面來發送設備維修保養通知,以確保設備得到及時的維護,同時提供通俗易懂的步驟和代碼說明。 什麼是API介面? 首先,讓 ...
  • Python安裝 許多PC和Mac已經預裝了Python。 要檢查在Windows PC上是否安裝了Python,請在開始菜單中搜索Python,或在命令行(cmd.exe)上運行以下命令: C:\Users\Your Name>python --version 要檢查在Linux或Mac上是否安裝 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...