分享
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。
* 首先context库的用法
```go
// context 库
func main(){
ctx, cancelFunc := context.WithCancel(context.Background())
go func(ctx context.Context){
var i int
for {
select {
case <-ctx.Done():
fmt.Println("cancel")
return
default:
}
i++
fmt.Println(i)
select {
case <-ctx.Done():
fmt.Println("cancel")
return
default:
}
i--
fmt.Println(i)
}
}(ctx)
time.Sleep(time.Second*2)
cancelFunc()
time.Sleep(time.Second*2)
}
```
* context库实现原理
```go
// context库实现原理
func main(){
ctx := make(chan struct{})
cancelFunc := func(){
ctx <- struct{}{}
}
go func(ctx chan struct{}){
var i int
for {
select {
case <-ctx:
fmt.Println("cancel")
return
default:
}
i++
fmt.Println(i)
select {
case <-ctx:
fmt.Println("cancel")
return
default:
}
i--
fmt.Println(i)
}
}(ctx)
time.Sleep(time.Second*2)
cancelFunc()
time.Sleep(time.Second*2)
}
```
* 使用flag
```go
func main(){
flag := true
cancelFunc := func(){
flag = false
}
go func(flag *bool){
var i int
for {
if !*flag {
fmt.Println("cancel")
return
}
i++
fmt.Println(i)
if !*flag {
fmt.Println("cancel")
return
}
i--
fmt.Println(i)
}
}(&flag)
time.Sleep(time.Second*2)
cancelFunc()
time.Sleep(time.Second*2)
}
```
* 使用channel比flag更优的地方
```go
//当然关于文件读写超时 *os.File有SetReadDeadline/SetWriteDeadline两个方法, 这里只是使用文件读取举个例子
func ReadFile(filename string, buf []byte )(complete chan struct{}, err error){
var fp *os.File
complete = make(chan struct{})
if fp,err = os.Open(filename); err != nil{
return
}
//一些golang初识者可能认为,随随便便的开启goroutinue是个不好的习惯,即使是用户态线程(我之前这么认为),
//但是再了解golang用户态线程调度的一些机制后,我可以大胆的告诉你,这东西就是这么用的,
//我在《多路IO复用事件驱动的服务器模型比阻塞IO多线程服务器模型高在哪?》这篇文章中有草草的写到,感兴趣的朋友可以去看一下
go func(chan struct{}){
_, _ = fp.Read(buf)
_ = fp.Close()
complete <- struct{}{}
}(complete)
return
}
func main(){
ctx := make(chan struct{})
cancelFunc := func(){
ctx <- struct{}{}
}
go func(ctx chan struct{}){
var i int
buf := make([]byte, 0x10)
for {
select {
case <-ctx:
fmt.Println("cancel")
return
default:
}
i++
fmt.Println(i)
select {
case <-ctx:
fmt.Println("cancel")
return
default:
}
i--
fmt.Println(i)
readComplete, err := ReadFile("./goroutine.log", buf)
if err!= nil{
fmt.Println(err.Error())
return
}
select {
case <-ctx:
fmt.Println("timeout!")
return
case <- readComplete:
fmt.Println(string(buf))
}
}
}(ctx)
time.Sleep(time.Second*2)
cancelFunc()
time.Sleep(time.Second*2)
}
```
有疑问加站长微信联系(非本文作者))
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
关注微信1054 次点击
添加一条新回复
(您需要 后才能回复 没有账号 ?)
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码` - 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传