(Go言語・WebAssembly)Webページで並列処理はできるのか?


前書き

Go言語を勉強する中でgoルーチンを使ってWebAsseblyにコンパイルした場合、
ブラウザ上で並列処理はきちんと行っているのか気になったので確認しました。

結果

問題なく並列処理ができました。
画面サンプル

以降はソースコードの記述です。
コンパイルの方法などは以前の記事を参照してください。
(Go言語)WebAssemblyで簡単なWebサイトを作ってみた

実行環境

OS:Windows 10 64bit
言語環境:go version go1.14.1
ブラウザ:Firefox バージョン: 74.0

ソースコード

htmlファイル
該当部分のみ抜粋
<body>
  <button type="submit" id="button1" >START</button><br>
  <div id="time1" >時刻1:</div>
  <div id="time2" >時刻2:</div>
  <div id="time3" >時刻3:</div>
</body>
時刻を取得し文字列を返す
func Get_time() string {
    now := time.Now()
    str := strconv.Itoa(now.Hour()) + ":" + strconv.Itoa(now.Minute()) + ":" + strconv.Itoa(now.Second())
    return str
}
メイン関数
package main
import (
    "strconv"
    "syscall/js"
    "time"
)
func main() {
    //イベントの管理-
    get_three_time("button1", "time1", "time2", "time3")
    <-make(chan struct{}, 0)
}
実装処理
func get_three_time(id string, output1 string, output2 string, output3 string) {
    //idから対象のオブジェクトを取得
    object := js.Global().Get("document").Call("getElementById", id)
    out1 := js.Global().Get("document").Call("getElementById", output1)
    out2 := js.Global().Get("document").Call("getElementById", output2)
    out3 := js.Global().Get("document").Call("getElementById", output3)
    //ゴールーチンで実行し
    action := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
        go func() {
            time.Sleep(time.Duration(0) * time.Second)//0秒待機
            out1.Set("innerText", "時刻1:"+Get_time())
        }()
        go func() {
            time.Sleep(time.Duration(2) * time.Second)//2秒待機
            out2.Set("innerText", "時刻2:"+Get_time())
        }()
        go func() {
            time.Sleep(time.Duration(4) * time.Second)//4秒待機
            out3.Set("innerText", "時刻3:"+Get_time())
        }()
        return nil
    })
    //アクションの呼び出し
    object.Call("addEventListener", "click", action)
}

結果・感想

Go言語+WebassemblyでGoルーチンによる並列処理を実装してみました。
もともとJavascritpには同期/非同期処理があり、それらと動作の違いはないかもしれません。

CPU視点で見れば、マルチスレッドによる非同期処理が役に立つ場面が存在しますが、
はたしてブラウザ上のバイナリコードが、複数のコア上で動作するのか?
という疑問が残ります。

仮説ですが、
スクリプトの実行がブラウザの1プロセス上として動作するならマルチスレッドとはなりませんし、ブラウザやCPUアーキテクチャに依存する可能性があります。

しかしながら、ソースコードで並列処理を実装できることはGo言語のメリットです。
フロントエンドにJavascriptやPHPなくGo言語を採用する理由の一つになるのではないでしょうか。

次はGo言語でAPIサーバを構築して、それをもとにSPAなwebページの構築を目指しています。
できる限りGo言語でWEBシステムを構築してくために少しづつですが前に進んでいる実感があります。
これからも頑張っていこうと思います。

ここまで読んできただきありがとうございました。