dsk49208 2018-10-01 06:33
浏览 46
已采纳

访问URL时终止go例程

I made a simple web app using Go. there is a goroutine which is executed when user access a URL, let say /inspection/start/. how to stop that goroutine when user access URL /inspection/stop/?

I heard about channel but I am not sure how to do it in my case.

here is the code:

func inspection_form_handler(w http.ResponseWriter, r *http.Request) {
    if r.FormValue("save") != "" {
        airport_id := getCurrentAirportId(r)

        r.ParseForm()
        if airport_id != nil {
            if r.FormValue("action") == "add"{
                go read_serial_port()
            }

            // redirect back to the list
            http.Redirect(w, r, "/airport#inspect", http.StatusSeeOther)
        }
    }
}

the routine function

func read_serial_port(){
    c := &serial.Config{Name:"/dev/ttyACM0", Baud:9600}
    s, err := serial.OpenPort(c)

    if err != nil {
        log.Fatal(err)
    }

    filename:= randSeq(10)+".txt"
    file, _ := os.Create("output/"+filename)

    defer file.Close();

    for{
        buf := make([]byte, 128)
        n, err := s.Read(buf)

        if err != nil {
            log.Fatal(err)
        }

        log.Printf("%s", string(buf[:n]))

        fmt.Fprintf(file, string(buf[:n]))

        time.Sleep(100 * time.Millisecond)
    }
}
  • 写回答

1条回答 默认 最新

  • douduan7295 2018-10-01 07:06
    关注

    you can make it by using time ticker and context

    func read_serial_port(c context.Context){
        c := &serial.Config{Name:"/dev/ttyACM0", Baud:9600}
        s, err := serial.OpenPort(c)
    
        if err != nil {
            log.Fatal(err)
        }
    
        filename:= randSeq(10)+".txt"
        file, _ := os.Create("output/"+filename)
    
        defer file.Close();
    
        ticker := time.NewTicker(100 * time.Millisecond)
        defer ticker.Stop()
    
        for{
            select {
            case <-c.Done():
                break
            case <-ticker.C:
                buf := make([]byte, 128)
                n, err := s.Read(buf)
    
                if err != nil {
                    log.Fatal(err)
                }
    
                log.Printf("%s", string(buf[:n]))
    
                fmt.Fprintf(file, string(buf[:n]))
    
                time.Sleep(100 * time.Millisecond)
            }
        }
    }
    

    then you need to add another route to call the cancel function

    if r.FormValue("action") == "add"{
        c, cnl := context.WithCancel(context.Background())
        // need to access this cancel function to use it in another route
        ExportedFunction = cnl
        go read_serial_port()
    }
    

    then cancel it by:

    func abortingMission(w http.ResponseWriter, r *http.Request) {
        ExportedFunction()
    }
    

    and also DON'T use underscore in your function name

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号