Skip to content

Instantly share code, notes, and snippets.

@zeusro
Last active November 17, 2020 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeusro/feb02745c6edc07b869df1132eee38d2 to your computer and use it in GitHub Desktop.
Save zeusro/feb02745c6edc07b869df1132eee38d2 to your computer and use it in GitHub Desktop.
一个chan string,实现chan互通讯。使用了两种实现方式。
package main
import (
"context"
"fmt"
"runtime"
"sync"
"time"
)
func main() {
// 参考链接:
// https://juejin.im/post/5a6873fef265da3e317e55b6#heading-8
// https://blog.csdn.net/xcl168/article/details/46464831
// https://www.kancloud.cn/digest/batu-go/153532
implement1()
implement2()
}
// implement1 用了 time.Sleep .这种实现方式比较"Java"
/*运行结果:
start
B<--A:六脉神剑
A-->B:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
A-->B:六脉神剑
B<--A:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
B<--A:六脉神剑
A-->B:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
A-->B:六脉神剑
B<--A:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
哼,谁让你们上课开小差的,通通给我出去罚站
*/
func implement1() {
ch := make(chan string, 1)
defer close(ch)
fmt.Println("implement1 start")
go func() {
for {
kongfu := "六脉神剑"
ch <- kongfu
fmt.Println("A-->B:" + kongfu)
enemyKongFu := <-ch
fmt.Println("A<--B:" + enemyKongFu)
time.Sleep(time.Second * 3)
}
}()
go func() {
for {
enemyKongFu := <-ch
fmt.Println("B<--A:" + enemyKongFu)
kongfu := "龟派气功"
fmt.Println("B-->A:" + kongfu)
ch <- kongfu
time.Sleep(time.Second * 2)
}
}()
time.Sleep(time.Second * 12)
runtime.Gosched()
fmt.Println("哼,谁让你们上课开小差的,通通给我出去罚站")
}
// implement2 利用了context的内置超时取消特性
/*运行结果:
start
程序将在2020-04-06 15:01:05.97913 +0800 CST m=+12.000253302结束
A-->B:六脉神剑
B<--A:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
A-->B:六脉神剑
B<--A:六脉神剑
B-->A:龟派气功
A<--B:龟派气功
B<--A:六脉神剑
B-->A:龟派气功
A-->B:六脉神剑
A<--B:龟派气功
A:有内鬼,终止交易
B:通道已关闭哼,谁让你们上课开小差的,通通给我出去罚站
*/
func implement2() {
ch := make(chan string, 1)
fmt.Println("implement2 start")
endDate := time.Now().Add(12 * time.Second)
fmt.Printf("程序将在%v结束\n", endDate)
ctx, cancel := context.WithDeadline(context.Background(), endDate)
var wg sync.WaitGroup
wg.Add(2)
go func(w *sync.WaitGroup, c context.Context) {
defer w.Done()
for {
select {
case <-time.After(time.Second * 3):
kongfu := "六脉神剑"
ch <- kongfu
fmt.Println("A-->B:" + kongfu)
enemyKongFu, ok := <-ch
if !ok {
fmt.Printf("A:通道已关闭")
return
}
fmt.Println("A<--B:" + enemyKongFu)
case <-c.Done():
fmt.Println("A:有内鬼,终止交易")
// chan 处理不好的话,容易死锁
//
close(ch)
return
// fmt.Println(c.Err())
}
}
}(&wg, ctx)
go func(w *sync.WaitGroup, c context.Context) {
defer w.Done()
for {
select {
case <-time.After(time.Second * 2):
enemyKongFu, ok := <-ch
if !ok {
fmt.Printf("B:通道已关闭")
return
}
fmt.Println("B<--A:" + enemyKongFu)
kongfu := "龟派气功"
fmt.Println("B-->A:" + kongfu)
ch <- kongfu
case <-c.Done():
fmt.Println("B:有内鬼,终止交易")
return
// fmt.Println(c.Err())
}
}
}(&wg, ctx)
defer func() {
cancel()
}()
wg.Wait()
fmt.Println("哼,谁让你们上课开小差的,通通给我出去罚站")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment