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

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

报告相同问题?

悬赏问题

  • ¥20 安装 opencv4nodejs 报错
  • ¥15 adb push异常 adb: error: 1409-byte write failed: Invalid argument
  • ¥15 nginx反向代理获取ip,java获取真实ip
  • ¥15 eda:门禁系统设计
  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA
  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!