diff --git a/README.md b/README.md index 1e8a049..353a4e4 100644 --- a/README.md +++ b/README.md @@ -30,5 +30,7 @@ | labs26 | 比较直接调用函数和反射调用函数的效率差别 | | labs27 | 测试不修改runtime代码的情况下获取goid的效率 | | labs28 | 测试`[]byte`转`string`的效率 | -| labs29 | 测试不同压缩算法压缩json数据的压缩比和压缩效率。| -| labs30 | 内存数据库事务Demo | \ No newline at end of file +| labs29 | 测试不同压缩算法压缩json数据的压缩比和压缩效率| +| labs30 | 内存数据库事务Demo | +| labs30 | 测试go对象的内存占用情况 | +| labs32 | 测试go对象在多线程环境下的切换时的线程安全及生命周期问题 | \ No newline at end of file diff --git a/labs31/README.md b/labs31/README.md new file mode 100644 index 0000000..21983b7 --- /dev/null +++ b/labs31/README.md @@ -0,0 +1,5 @@ +测试go对象的内存占用情况。 + + size of int: 8 + size of main.Date: 24 + size of [100]main.Date: 2400 diff --git a/labs31/labs31.go b/labs31/labs31.go new file mode 100644 index 0000000..178f640 --- /dev/null +++ b/labs31/labs31.go @@ -0,0 +1,16 @@ +package main + +import "unsafe" +import "fmt" + +type Date struct { + Day int + Month int + Year int +} + +func main() { + fmt.Printf("size of %T: %v\n", 0, unsafe.Sizeof(0)) + fmt.Printf("size of %T: %v\n", Date{}, unsafe.Sizeof(Date{})) + fmt.Printf("size of %T: %v\n", [100]Date{}, unsafe.Sizeof([100]Date{})) +} \ No newline at end of file diff --git a/labs32/README.md b/labs32/README.md new file mode 100644 index 0000000..5e444d5 --- /dev/null +++ b/labs32/README.md @@ -0,0 +1,8 @@ +测试go对象在多线程环境下的切换时的线程安全及生命周期问题。 + +给定这样一个应用场景: + +有一个http server,启动时会使用一个全局的对象来存取一些数据,例如叫`RuleData`,每个请求来的时候会使用(只读)这个`RuleData`。另外,当这个数据有更新时,我们希望该http server能自动更新这个`RuleData`,而又不影响当前的请求。 + +结论:如果处理得当(例如加锁)是没有问题的。 + diff --git a/labs32/labs32.go b/labs32/labs32.go new file mode 100644 index 0000000..fd24423 --- /dev/null +++ b/labs32/labs32.go @@ -0,0 +1,65 @@ +package main + +import ( + "fmt" + "math/rand" + "sync" + "time" +) + +type Date struct { + i1 int + i2 int + i3 int +} + +var global *Date +var mutex sync.Mutex + +func Update() { + d := new(Date) + d.i1 = time.Now().Nanosecond() + d.i2 = d.i1 + 1 + d.i3 = d.i1 + 2 + mutex.Lock() + defer mutex.Unlock() + global = d +} + +func Get() *Date { + mutex.Lock() + defer mutex.Unlock() + return global +} + +func Process(c int, w *sync.WaitGroup) { + d := Get() + for i := 0; i < 10; i++ { + fmt.Printf("c=%d i=%d i1=%d i2=%d i3=%d\n", c, i, d.i1, d.i2, d.i3) + time.Sleep(time.Millisecond * time.Duration(rand.Int()%1000+500)) + } + w.Done() +} + +func main() { + Update() + var w sync.WaitGroup + go func() { + w.Add(1) + for i := 0; i < 10000; i++ { + Update() + time.Sleep(time.Millisecond * 20) + } + w.Done() + }() + + for i := 0; i < 100; i++ { + go Process(i, &w) + w.Add(1) + time.Sleep(time.Millisecond*100) + } + + + + w.Wait() +}