* 首先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)
}
```
有疑问加站长微信联系(非本文作者))