Go公式WikiのLock OS Threadの日本語意訳になります。
(元記事の最終更新日: 2015/01/27 rev.4)
Lock OS Thread
はじめに
いくつかのライブラリ、特にCocoa, OpenGL, libSDLのようなグラフィカルフレームワークやライブラリは全て、スレッドローカルのデータ構造を使用するため、メインOSスレッドや同じOSスレッドから呼び出される必要があります。
これに対して、GoのランタイムはLockOSThread()
関数を提供していますが、正しく使うことが難しいことで有名です。
解法
この問題に対して該当スレッドにて、Russ Cox氏が良い解法を説明しています。
package sdl
// main.main関数をメインスレッドで実行するように調整
func init() {
runtime.LockOSThread()
}
// Main 関数はSDLのメインサービスループを実行します。
// バイナリのmain.mainはこのループを実行するためにsdl.Main()を呼び出す必要があります。
// Main 関数はreturnしません。
// もし他の作業が必要な場合は、別のゴルーチンで行う必要があります。
func Main() {
for f := range mainfunc {
f()
}
}
// do 関数はメインスレッドにて f を実行する
func do(f func()) {
done := make(chan bool, 1)
mainfunc <- func() {
f()
done <- true
}
<-done
}
// メインスレッドにて実行する作業キュー
var mainfunc = make(chan func())
訳注:
var mainfunc = make(chan func())
でシンタックスハイライトが崩れてしまうため、原文とは意図的に配置を変えています。
そして、パッケージsdk内の他の関数は以下のようになります。
func Beep() {
do(func() {
// メインスレッドで実行しないといけない処理
})
}
comments powered by Disqus