context finished but not practice
parent
f8dda033a4
commit
1b56fec40f
|
@ -0,0 +1,43 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
|
//var notify bool
|
||||||
|
|
||||||
|
//var exitChan chan bool = make(chan bool, 1)
|
||||||
|
|
||||||
|
// why context
|
||||||
|
|
||||||
|
func f() {
|
||||||
|
defer wg.Done()
|
||||||
|
//loop:
|
||||||
|
for {
|
||||||
|
fmt.Println("hello world")
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
//if notify {
|
||||||
|
// break
|
||||||
|
//} //变量
|
||||||
|
//select {
|
||||||
|
//case <-exitChan:
|
||||||
|
// break loop
|
||||||
|
//default:
|
||||||
|
//} //channel 版本
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
wg.Add(1)
|
||||||
|
go f()
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
//如何通知goroutine退出?
|
||||||
|
//exitChan <- true
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func gen(ctx context.Context) <-chan int {
|
||||||
|
dst := make(chan int)
|
||||||
|
n := 1
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return // return结束该goroutine,防止泄露
|
||||||
|
case dst <- n:
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel() // 当我们取完需要的整数后调用cancel
|
||||||
|
|
||||||
|
for n := range gen(ctx) {
|
||||||
|
fmt.Println(n)
|
||||||
|
if n == 5 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
d := time.Now().Add(2000 * time.Millisecond)
|
||||||
|
ctx, cancel := context.WithDeadline(context.Background(), d)
|
||||||
|
|
||||||
|
// 尽管ctx会过期,但在任何情况下调用它的cancel函数都是很好的实践。
|
||||||
|
// 如果不这样做,可能会使上下文及其父类存活的时间超过必要的时间。
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(1 * time.Second):
|
||||||
|
fmt.Println("overslept")
|
||||||
|
case <-ctx.Done():
|
||||||
|
fmt.Println(ctx.Err())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// context.WithTimeout
|
||||||
|
|
||||||
|
var Wg sync.WaitGroup
|
||||||
|
|
||||||
|
func worker(ctx context.Context) {
|
||||||
|
LOOP:
|
||||||
|
for {
|
||||||
|
fmt.Println("db connecting ...")
|
||||||
|
time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒
|
||||||
|
select {
|
||||||
|
case <-ctx.Done(): // 50毫秒后自动调用
|
||||||
|
break LOOP
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("worker done!")
|
||||||
|
Wg.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 设置一个50毫秒的超时
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
|
||||||
|
Wg.Add(1)
|
||||||
|
go worker(ctx)
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
cancel() // 通知子goroutine结束
|
||||||
|
Wg.Wait()
|
||||||
|
fmt.Println("over")
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// context.WithValue
|
||||||
|
|
||||||
|
type TraceCode string
|
||||||
|
|
||||||
|
var wait sync.WaitGroup
|
||||||
|
|
||||||
|
func workerProc(ctx context.Context) {
|
||||||
|
key := TraceCode("TRACE_CODE")
|
||||||
|
traceCode, ok := ctx.Value(key).(string) // 在子goroutine中获取trace code
|
||||||
|
if !ok {
|
||||||
|
fmt.Println("invalid trace code")
|
||||||
|
}
|
||||||
|
LOOP:
|
||||||
|
for {
|
||||||
|
fmt.Printf("worker, trace code:%s\n", traceCode)
|
||||||
|
time.Sleep(time.Millisecond * 10) // 假设正常连接数据库耗时10毫秒
|
||||||
|
select {
|
||||||
|
case <-ctx.Done(): // 50毫秒后自动调用
|
||||||
|
break LOOP
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println("worker done!")
|
||||||
|
wait.Done()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 设置一个50毫秒的超时
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*50)
|
||||||
|
// 在系统的入口中设置trace code传递给后续启动的goroutine实现日志数据聚合
|
||||||
|
ctx = context.WithValue(ctx, TraceCode("TRACE_CODE"), "12512312234")
|
||||||
|
wait.Add(1)
|
||||||
|
go workerProc(ctx)
|
||||||
|
time.Sleep(time.Second * 5)
|
||||||
|
cancel() // 通知子goroutine结束
|
||||||
|
wait.Wait()
|
||||||
|
fmt.Println("over")
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var WG sync.WaitGroup
|
||||||
|
|
||||||
|
func f1(ctx context.Context) {
|
||||||
|
defer WG.Done()
|
||||||
|
go f2(ctx)
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
fmt.Println("hello world")
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
break loop
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
func f2(ctx context.Context) {
|
||||||
|
defer WG.Done()
|
||||||
|
loop:
|
||||||
|
for {
|
||||||
|
fmt.Println("hello wangao")
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
break loop
|
||||||
|
default:
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
WG.Add(1)
|
||||||
|
go f1(ctx)
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
//如何通知goroutine退出?
|
||||||
|
cancel()
|
||||||
|
WG.Wait()
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
如何优雅的控制子goroutine退出?
|
|
@ -0,0 +1,47 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type ListNode struct {
|
||||||
|
Val int
|
||||||
|
Next *ListNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func reverseList(head *ListNode) *ListNode {
|
||||||
|
var pre *ListNode
|
||||||
|
cur := head
|
||||||
|
for cur != nil {
|
||||||
|
tmp := cur.Next //暂存初始方向
|
||||||
|
cur.Next = pre //改变链表方向
|
||||||
|
pre = cur //移动指针
|
||||||
|
cur = tmp //移动指针2
|
||||||
|
}
|
||||||
|
return pre
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
head := &ListNode{
|
||||||
|
Val: 1,
|
||||||
|
Next: &ListNode{
|
||||||
|
Val: 2,
|
||||||
|
Next: &ListNode{
|
||||||
|
Val: 3,
|
||||||
|
Next: &ListNode{
|
||||||
|
Val: 4,
|
||||||
|
Next: &ListNode{
|
||||||
|
Val: 5,
|
||||||
|
Next: nil,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fmt.Printf("%#v\n", head)
|
||||||
|
ret := reverseList(head) //反转之后的头节点
|
||||||
|
fmt.Printf("%#v\n", ret)
|
||||||
|
for ret != nil {
|
||||||
|
fmt.Print(ret.Val, "->")
|
||||||
|
ret = ret.Next //指针移动,直到链表的尾部
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue