Skip to content

Commit 7e4e535

Browse files
authored
Merge pull request #707 from devlights:add-sync-pool-example
Add examples/basic/syncs/use_pool.go
2 parents 1f202c9 + cd33a95 commit 7e4e535

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

examples/basic/syncs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@
1717
|use\_oncefunc.go|syncs\_use\_oncefunc|Go 1.21 で追加された sync.OnceFunc() のサンプルです|
1818
|use\_oncevalue.go|syncs\_use\_oncevalue|Go 1.21 で追加された sync.OnceValue() のサンプルです|
1919
|use\_oncevalues.go|syncs\_use\_oncevalues|Go 1.21 で追加された sync.OnceValues() のサンプルです|
20+
|use\_pool.go|syncs\_use\_pool|sync.Poolのサンプルです|

examples/basic/syncs/examples.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,5 @@ func (r *register) Regist(m mapping.ExampleMapping) {
2626
m["syncs_use_oncefunc"] = UseOnceFunc
2727
m["syncs_use_oncevalue"] = UseOnceValue
2828
m["syncs_use_oncevalues"] = UseOnceValues
29+
m["syncs_use_pool"] = UsePool
2930
}

examples/basic/syncs/use_pool.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package syncs
2+
3+
import (
4+
"sync"
5+
6+
"github.com/devlights/gomy/output"
7+
)
8+
9+
type _PooledObject struct {
10+
v int
11+
}
12+
13+
func NewPooledObject(v int) *_PooledObject {
14+
output.Stderrl("[New]", "Call NewPooledObject()")
15+
return &_PooledObject{v: v}
16+
}
17+
18+
func (me *_PooledObject) Reset() {
19+
me.v = 0
20+
}
21+
22+
func (me *_PooledObject) Set(v int) {
23+
me.v = v + 100
24+
}
25+
26+
func (me *_PooledObject) Value() int {
27+
return me.v
28+
}
29+
30+
// UsePool は、sync.Poolのサンプルです。
31+
//
32+
// # REFERENCES
33+
// - https://pkg.go.dev/sync@go1.21.4#Pool
34+
func UsePool() error {
35+
//
36+
// sync.Pool を利用する際の注意点 (go doc より引用)
37+
//
38+
// > Any item stored in the Pool may be removed automatically at any time without notification.
39+
// > If the Pool holds the only reference when this happens, the item might be deallocated.
40+
//
41+
// プールに保持されているオブジェクトは通知無しに自動削除される可能性がある。
42+
// その際に、プールがそのオブジェクトを参照する唯一であれば、メモリから
43+
// 開放される可能性がある。
44+
//
45+
// > A Pool must not be copied after first use.
46+
//
47+
// プールは、最初に使用した後はコピーしてはならない。
48+
//
49+
// > The Pool's New function should generally only return pointer types,
50+
// > since a pointer can be put into the return interface value without an allocation
51+
//
52+
// ポインタは割り当てなしで戻りインターフェイス値に入れることができるため、
53+
// プールの New 関数は通常、ポインタ型のみを返す必要がある.
54+
//
55+
56+
const (
57+
NUM_ITEMS = 20
58+
)
59+
60+
var (
61+
pool = sync.Pool{
62+
New: func() any {
63+
return NewPooledObject(0)
64+
},
65+
}
66+
ch = make(chan int)
67+
done = make(chan struct{})
68+
wg = sync.WaitGroup{}
69+
)
70+
71+
wg.Add(NUM_ITEMS)
72+
73+
for i := 0; i < NUM_ITEMS; i++ {
74+
go func(i int, ch chan<- int) {
75+
defer wg.Done()
76+
77+
// プールから取得
78+
o := pool.Get().(*_PooledObject)
79+
80+
o.Reset()
81+
o.Set(i)
82+
v := o.Value()
83+
84+
// 使い終わったらプールに戻す
85+
pool.Put(o)
86+
87+
ch <- v
88+
}(i, ch)
89+
}
90+
91+
go func() {
92+
defer close(ch)
93+
wg.Wait()
94+
}()
95+
96+
go func(done chan<- struct{}, ch <-chan int) {
97+
defer close(done)
98+
99+
for v := range ch {
100+
output.Stderrl("[output]", v)
101+
}
102+
}(done, ch)
103+
104+
<-done
105+
106+
return nil
107+
}

0 commit comments

Comments
 (0)