zoukankan      html  css  js  c++  java
  • context关闭goroutine

    package main
    
    import (
    	"context"
    	"fmt"
    	"time"
    )
    
    func f2(ctx context.Context) {
    	n := 1
    	for {
    		time.Sleep(2 * time.Second)
    		select {
    		case <-ctx.Done():
    			fmt.Printf("%s 结束运行
    ", "f2")
    			return
    		default:
    			fmt.Println("f2---------------->", n)
    			n++
    		}
    	}
    
    }
    
    func f1(ctx context.Context) {
    	go f2(ctx)
    	n := 1
    	for {
    		time.Sleep(time.Second)
    		select {
    		case <-ctx.Done():
    			fmt.Printf("%s 结束运行
    ", ctx.Err())
    			return
    		default:
    			fmt.Println("f1--->", n)
    			n++
    		}
    	}
    
    }
    
    func main() {
    	// 创建
    	ctx, cancel := context.WithCancel(context.Background())
    	go f1(ctx)
    	time.Sleep(time.Second * 10)
    	// 调用cancel方法时,会给ctx.Done这个chan就
    	cancel()
    
    
    	for{
    		println("main....")
    		time.Sleep(time.Second)
    	}
    
    }
    
    

    打印结果

    f1---> 1
    f1---> 2
    f2----------------> 1
    f1---> 3
    f1---> 4
    f2----------------> 2
    f1---> 5
    f1---> 6
    f2----------------> 3
    f1---> 7
    f1---> 8
    f2----------------> 4
    f1---> 9
    main....
    f2 结束运行
    context canceled 结束运行
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    main....
    

    结论:通过上面的打印记录可以知道,在主程中调用cancel方法后,它与之相关联的f1f2 两个函数中ctx.Done() 这个分支的case 都触发了, 这说context底层在我们调用cancel方法时,往ctx.Done这个管道中写了数据。 本例也正是用此特性完成了goroutine的退出。

  • 相关阅读:
    软件开发术语
    网络规划与设计
    MPLS LDP协议
    MPLS 基础
    CallAfter
    LongRunningTasks
    Non-blocking GUI
    WorkingWithThreads
    Python: Running Ping, Traceroute and More
    wxPython and Threads
  • 原文地址:https://www.cnblogs.com/z-qinfeng/p/13649147.html
Copyright © 2011-2022 走看看