ch3.8: 增加例子代码

This commit is contained in:
chai2010 2019-08-05 11:06:38 +08:00
parent 4bc303bd53
commit bbb1dea40f
12 changed files with 244 additions and 0 deletions

View File

@ -0,0 +1,5 @@
package main
func main() {
panic("goid")
}

View File

@ -0,0 +1,9 @@
package main
import "runtime"
func main() {
var buf = make([]byte, 64)
var stk = buf[:runtime.Stack(buf, false)]
println(string(stk))
}

View File

@ -0,0 +1,34 @@
package main
import (
"fmt"
"runtime"
"strconv"
"strings"
"time"
)
func main() {
println("a:", GetGoid())
go func() {
println("b:", GetGoid())
}()
time.Sleep(time.Second)
}
func GetGoid() int64 {
var (
buf [64]byte
n = runtime.Stack(buf[:], false)
stk = strings.TrimPrefix(string(buf[:n]), "goroutine ")
)
idField := strings.Fields(stk)[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Errorf("can not get goroutine id: %v", err))
}
return int64(id)
}

View File

@ -0,0 +1,19 @@
package main
import (
"unsafe"
)
func getg() unsafe.Pointer
const g_goid_offset = 152 // Go1.8/Go1.9/Go1.10/Go1.11/Go1.12/Go1.13
func GetGroutineId() int64 {
g := getg()
p := (*int64)(unsafe.Pointer(uintptr(g) + g_goid_offset))
return *p
}
func main() {
println(GetGroutineId())
}

View File

@ -0,0 +1,7 @@
#include "textflag.h"
// func getg() unsafe.Pointer
TEXT ·getg(SB), NOSPLIT, $0-8
MOVQ (TLS), AX
MOVQ AX, ret+0(FP)
RET

View File

@ -0,0 +1,34 @@
package main
import (
"reflect"
"time"
)
func getg() interface{}
type eface struct {
_type, elem uintptr
}
//go:nosplit
func runtime_convT2E_hack(_type, elem uintptr) eface {
return eface{
_type: _type,
elem: elem,
}
}
func GetGoid() int64 {
g := getg()
goid := reflect.ValueOf(g).FieldByName("goid").Int()
return goid
}
func main() {
println("a:", GetGoid())
go func() {
println("b:", GetGoid())
}()
time.Sleep(time.Second)
}

View File

@ -0,0 +1,20 @@
#include "textflag.h"
// func getg() interface{}
TEXT ·getg(SB), NOSPLIT, $32-16
// get runtime.g
MOVQ (TLS), AX
// get runtime.g type
MOVQ $type·runtime·g(SB), BX
// convert (*g) to interface{}
MOVQ AX, 8(SP)
MOVQ BX, 0(SP)
CALL ·runtime_convT2E_hack(SB)
MOVQ 16(SP), AX
MOVQ 24(SP), BX
// return interface{}
MOVQ AX, ret+0(FP)
MOVQ BX, ret+8(FP)
RET

View File

@ -0,0 +1,43 @@
package gls
import "sync"
var gls struct {
m map[int64]map[interface{}]interface{}
sync.Mutex
}
func init() {
gls.m = make(map[int64]map[interface{}]interface{})
}
func getMap() map[interface{}]interface{} {
gls.Lock()
defer gls.Unlock()
goid := GetGoid()
if m, _ := gls.m[goid]; m != nil {
return m
}
m := make(map[interface{}]interface{})
gls.m[goid] = m
return m
}
func Get(key interface{}) interface{} {
return getMap()[key]
}
func Put(key interface{}, v interface{}) {
getMap()[key] = v
}
func Delete(key interface{}) {
delete(getMap(), key)
}
func Clean() {
gls.Lock()
defer gls.Unlock()
delete(gls.m, GetGoid())
}

View File

@ -0,0 +1,25 @@
package gls
import (
"reflect"
)
func getg() interface{}
type eface struct {
_type, elem uintptr
}
//go:nosplit
func runtime_convT2E_hack(_type, elem uintptr) eface {
return eface{
_type: _type,
elem: elem,
}
}
func GetGoid() int64 {
g := getg()
goid := reflect.ValueOf(g).FieldByName("goid").Int()
return goid
}

View File

@ -0,0 +1,20 @@
#include "textflag.h"
// func getg() interface{}
TEXT ·getg(SB), NOSPLIT, $32-16
// get runtime.g
MOVQ (TLS), AX
// get runtime.g type
MOVQ $type·runtime·g(SB), BX
// convert (*g) to interface{}
MOVQ AX, 8(SP)
MOVQ BX, 0(SP)
CALL ·runtime_convT2E_hack(SB)
MOVQ 16(SP), AX
MOVQ 24(SP), BX
// return interface{}
MOVQ AX, ret+0(FP)
MOVQ BX, ret+8(FP)
RET

View File

@ -0,0 +1,3 @@
module gobook/ch3.8-6
go 1.13

View File

@ -0,0 +1,25 @@
package main
import (
"fmt"
"sync"
"gobook/ch3.8-6/gls"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(idx int) {
defer wg.Done()
defer gls.Clean()
defer func() {
fmt.Printf("%d: number = %d\n", idx, gls.Get("number"))
}()
gls.Put("number", idx+100)
}(i)
}
wg.Wait()
}