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

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

报告相同问题?

悬赏问题

  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮