golangサポートtls
前言
golangの公式デフォルトはtls(Thread Local Storage)をサポートしていません.tlsをサポートする言語も多くありません.例えば、C++やGCC-C(gccのc言語拡張、linux用).goはtlsの実装を公式に拒否し,tls問題を解決するためにコンテキストcontextパケットを導入した(閉パケットもある程度コンテキストである).ローカル変数は、コンテキストパラメータ伝達によって伝達されます.この方法の利点は明示的なコンテキストが明確であり,悪い点は各関数に1つのコンテキストパラメータが必要であり,伝達されることである.ハッカーはもちろんこれに満足しないで、そこで1人の兄たちはgo-tlsをオープンソースしましたhttps://github.com/huandu/go-tlsコードは複雑ではなく、使用も簡単です.そのREADを参考にすればいいです.
go-tlsの原理
実装原理を簡単に説明します.各コヒーレンスにグローバル一意のインクリメントidを定義し、各コヒーレンスのデータを格納するためにグローバルmapを定義します.mapのkeyは、コヒーレントなg構造アドレスであり、データがコヒーレントに局所的であることを保証する.mapはグローバルであるため,複数のコヒーレンスが同時にアクセスし,臨界領域に属するため,読み書きロックが追加された.以下の定義
Get/set/Delインタフェースを使用して、コパスのデータを取得、追加、削除します.
コプロセッサのデータは、コプロセッサの終了時に解放される必要がある場合があり、go−tlsは、FILOルールに従って実行される終了関数リストを導入した.
AtExitインタフェースで終了プロセッサを追加します.
次に、コヒーレントのgを取得するアセンブリによって実現される
goのデフォルトgoexitをカスタムhackedGoexitに置き換えた特殊なハッカー技術により、上記のatExitFuncsの呼び出しを実現します.goexitを参照してください.go
このようにコヒーレントなtlsを実現した.contextの使用はある程度避けることができますが、もちろん公式の主張とは一致しません.
リスクは、goコンパイラの後期にこのような更新があるかどうかという互換性を考慮する必要があります.goexitを置き換えるプロセスのようなハッカー技術を使用しているため、これは下位層と強く依存しています. 読み書きロックを使用しているため、性能に敏感なニーズは慎重にしてください.syncをお勧めするかもしれません.Mapは普通のmap+読み書きロックの方式を置き換えて、実は私はあなたに教えて、個人はすでに単機で測定したことがあって、それらの2つの性能は相当して、甚だしきに至っては後者はsyncより優れています.Mapはまだほんの少しです. メンテナンスコストを考慮する.公式推奨contextのためです. 協程ではtlsを伝達できない.
以上の4点に敏感でない需要シーンであれば、安心して使用できます.
golangの公式デフォルトはtls(Thread Local Storage)をサポートしていません.tlsをサポートする言語も多くありません.例えば、C++やGCC-C(gccのc言語拡張、linux用).goはtlsの実装を公式に拒否し,tls問題を解決するためにコンテキストcontextパケットを導入した(閉パケットもある程度コンテキストである).ローカル変数は、コンテキストパラメータ伝達によって伝達されます.この方法の利点は明示的なコンテキストが明確であり,悪い点は各関数に1つのコンテキストパラメータが必要であり,伝達されることである.ハッカーはもちろんこれに満足しないで、そこで1人の兄たちはgo-tlsをオープンソースしましたhttps://github.com/huandu/go-tlsコードは複雑ではなく、使用も簡単です.そのREADを参考にすればいいです.
go-tlsの原理
実装原理を簡単に説明します.各コヒーレンスにグローバル一意のインクリメントidを定義し、各コヒーレンスのデータを格納するためにグローバルmapを定義します.mapのkeyは、コヒーレントなg構造アドレスであり、データがコヒーレントに局所的であることを保証する.mapはグローバルであるため,複数のコヒーレンスが同時にアクセスし,臨界領域に属するため,読み書きロックが追加された.以下の定義
var (
tlsDataMap = map[unsafe.Pointer]*tlsData{
}
tlsMu sync.RWMutex
tlsUniqueID int64
)
Get/set/Delインタフェースを使用して、コパスのデータを取得、追加、削除します.
コプロセッサのデータは、コプロセッサの終了時に解放される必要がある場合があり、go−tlsは、FILOルールに従って実行される終了関数リストを導入した.
type tlsData struct {
id int64
data dataMap
atExitFuncs []func()
}
AtExitインタフェースで終了プロセッサを追加します.
次に、コヒーレントのgを取得するアセンブリによって実現される
TEXT ·getg(SB), NOSPLIT, $0-8
get_tls(CX) //MOVQ TLS, CX
MOVQ g(CX), AX //0(CX)(TLS*1)
MOVQ AX, ret+0(FP)
RET
goのデフォルトgoexitをカスタムhackedGoexitに置き換えた特殊なハッカー技術により、上記のatExitFuncsの呼び出しを実現します.goexitを参照してください.go
このようにコヒーレントなtlsを実現した.contextの使用はある程度避けることができますが、もちろん公式の主張とは一致しません.
リスク
以上の4点に敏感でない需要シーンであれば、安心して使用できます.