```package main
import (
"time"
)
func main() {
t := time.NewTimer(100 * time.Hour)
for i := 0; i < 8; i++ {
go func() {
for {
t.Reset(100 * time.Hour)
}
}()
}
select {}
}```
在实际应用中,收包通过chan控制,但都需要加定时来控制写入超时,如果timer.reset还需要加锁来处理的话,那么chan就相当于是摆设了。
```
package main
import (
"fmt"
"time"
)
type BaseTimeTest struct {
conTimer *time.Timer
bufferChan chan uint16
}
func NewBaseTimeTest() *BaseTimeTest {
this := &BaseTimeTest{}
this.conTimer = time.NewTimer(time.Duration(3) * time.Second)
this.bufferChan = make(chan uint16, 10)
return this
}
//向worker push数据
func (this *BaseTimeTest) PushData(data uint16) {
if len(this.conTimer.C) > 0 {
fmt.Println("Timeout New", time.Now().Unix())
this.conTimer = time.NewTimer(time.Duration(3) * time.Second)
} else {
fmt.Println("Reset", time.Now().UnixNano())
this.conTimer.Reset(time.Duration(3) * time.Second)
}
select {
case this.bufferChan <- data:
fmt.Println("len:", len(this.bufferChan), " data:", data)
case tmd := <-this.conTimer.C:
fmt.Println("len:", len(this.bufferChan), "timeout", tmd.UnixNano())
}
//this.conTimer.Stop()
}
func (this *BaseTimeTest) Reset() {
fmt.Println("--Reset time", time.Now().UnixNano())
this.conTimer.Reset(time.Duration(3) * time.Second)
}
func main() {
tIns := NewBaseTimeTest()
go func() {
for {
tIns.PushData(1)
}
}()
go func() {
for {
tIns.Reset()
time.Sleep(time.Duration(2999) * time.Millisecond)
tIns.Reset()
time.Sleep(time.Duration(3000) * time.Millisecond)
}
}()
select {}
}
```
golang 1.9.7表示毫无压力
--Reset time 1536120378691200000
len: 10 timeout 1536120378691200000
![image.png](https://static.studygolang.com/180905/b25665c95c1113e09399e8b93b49f41f.png)
注释上又说reset和t.c的写入竞态,到底是否线程安全?
使用golang 1.10以上版本直接挂,对比time包没啥改变,应该是底层c函数改了。
#4
更多评论
超时一般不是这么写么
```golang
select {
case t:=<-c:
// do something
case <-time.After(time.Second*10):
// time out
}
```
你这个怎么是用timer来做的?t.Reset 无论哪个版本都是非线程安全的。
#2