File tree Expand file tree Collapse file tree 6 files changed +163
-15
lines changed
Expand file tree Collapse file tree 6 files changed +163
-15
lines changed Original file line number Diff line number Diff line change 1- # Binaries for programs and plugins
2- * .exe
3- * .exe~
4- * .dll
5- * .so
6- * .dylib
7-
8- # Test binary, built with `go test -c`
9- * .test
10-
11- # Output of the go coverage tool, specifically when used with LiteIDE
12- * .out
13-
14- # Dependency directories (remove the comment below to include it)
15- # vendor/
1+ .idea /*
Original file line number Diff line number Diff line change 11# gls
22goroutine local storage
3+
4+ # demo
5+ ```
6+ package main
7+
8+ import (
9+ "fmt"
10+ "github.com/go-basic/gls"
11+ "sync"
12+ )
13+
14+ func main() {
15+ var wg sync.WaitGroup
16+ for i := 0; i < 5; i++ {
17+ wg.Add(1)
18+ go func(idx int) {
19+ defer wg.Done()
20+ defer gls.Clean()
21+
22+ defer func() {
23+ fmt.Printf("%d: number = %d\n", idx, gls.Get("number"))
24+ }()
25+ gls.Set("number", idx+100)
26+ }(i)
27+ }
28+ wg.Wait()
29+ }
30+
31+ ```
Original file line number Diff line number Diff line change 1+ package main
2+
3+ import (
4+ "fmt"
5+ "github.com/go-basic/gls"
6+ "sync"
7+ )
8+
9+ func main () {
10+ var wg sync.WaitGroup
11+ for i := 0 ; i < 5 ; i ++ {
12+ wg .Add (1 )
13+ go func (idx int ) {
14+ defer wg .Done ()
15+ defer gls .Clean ()
16+
17+ defer func () {
18+ fmt .Printf ("%d: number = %d\n " , idx , gls .Get ("number" ))
19+ }()
20+ gls .Set ("number" , idx + 100 )
21+ }(i )
22+ }
23+ wg .Wait ()
24+ }
Original file line number Diff line number Diff line change 1+ package gls
2+
3+ import (
4+ "fmt"
5+ "runtime"
6+ "strconv"
7+ "strings"
8+ "sync"
9+ )
10+
11+ var gls struct {
12+ m map [int64 ]map [interface {}]interface {}
13+ sync.RWMutex
14+ }
15+
16+ func init () {
17+ gls .m = make (map [int64 ]map [interface {}]interface {})
18+ }
19+
20+ func GetGoId () int64 {
21+ var (
22+ buf [64 ]byte
23+ n = runtime .Stack (buf [:], false )
24+ stk = strings .TrimPrefix (string (buf [:n ]), "goroutine " )
25+ )
26+ idField := strings .Fields (stk )[0 ]
27+ id , err := strconv .Atoi (idField )
28+ if err != nil {
29+ panic (fmt .Errorf ("can not get goroutine id: %v" , err ))
30+ }
31+ return int64 (id )
32+ }
33+
34+ func Get (key interface {}) interface {} {
35+ gls .RLock ()
36+ defer gls .RUnlock ()
37+ goId := GetGoId ()
38+ return gls.m [goId ][key ]
39+ }
40+
41+ func Set (key interface {}, v interface {}) {
42+ gls .Lock ()
43+ defer gls .Unlock ()
44+ goId := GetGoId ()
45+ if _ , ok := gls.m [goId ][key ]; ! ok {
46+ gls .m [goId ] = make (map [interface {}]interface {})
47+ }
48+ gls.m [goId ][key ] = v
49+ }
50+
51+ func Clean () {
52+ gls .Lock ()
53+ defer gls .Unlock ()
54+ delete (gls .m , GetGoId ())
55+ }
Original file line number Diff line number Diff line change 1+ package gls
2+
3+ import (
4+ "fmt"
5+ "strconv"
6+ "testing"
7+ )
8+
9+ var key = "test"
10+
11+ func GO (fn func ()) {
12+ go fn ()
13+ }
14+
15+ func TestGls (t * testing.T ) {
16+ GO (func () {
17+ defer Clean ()
18+ Set (key , "aaa" )
19+ testPrint ()
20+ })
21+ GO (func () {
22+ defer Clean ()
23+ Set (key , "bbb" )
24+ testPrint ()
25+ })
26+ GO (func () {
27+ defer Clean ()
28+ Set (key , "ccc" )
29+ testPrint ()
30+ })
31+ }
32+
33+
34+ func BenchmarkGls (b * testing.B ) {
35+ for i := 0 ; i < b .N ; i ++ {
36+ GO (func () {
37+ defer Clean ()
38+ Set (key , "ccc" + strconv .FormatInt (GetGoId (), 10 ))
39+ testGet ()
40+ })
41+ }
42+ }
43+
44+ func testPrint () {
45+ fmt .Println (Get (key ), GetGoId ())
46+ }
47+
48+ func testGet () {
49+ Get (key )
50+ }
51+
Original file line number Diff line number Diff line change 1+ module github.com/go-basic/gls
2+
3+ go 1.15
You can’t perform that action at this time.
0 commit comments