douya2006 2017-03-26 22:26
浏览 41

一定时间后如何取消goroutine

I am making a load testing tool that makes multiple HTTP calls in goroutines, and it works, but now I am trying to allow it to run for only a specified duration.

How can I cancel the goroutines when the sleep has finished?

What I am currently attempting to do is to make a goroutine that does time.Sleep() for the specified duration, and when that is finished it will broadcast a message to the channel.

In my infinite loop, I listen for the message in the switch statement, and when it is there I return. This works just as I want it to.

The problem is, the goroutines from the go httpPost() line will continue making HTTP calls. I even attempt to pass the channel into that function and listen for the same CALL_TIME_RAN_OUT message there as well, but for whatever reason when I do that the goroutines only run once and then immediately return, as opposed to waiting for the message to be broadcasted by the end of the Sleep.

Does anyone know a better approach I can take? This doesn't seem to be working.

Here's the code (removed irrelevant parts):

func attack(cfg AttackConfig) {
    // some code ...

    var ar attackResponse
    ch := make(chan uint8, 8)

    go func() {
        time.Sleep(cfg.Duration * time.Second)
        ch <- CALL_TIME_RAN_OUT
    }()

    for {
        if atomic.LoadInt32(&currConnections) < atomic.LoadInt32(&maxConnections) - 1 {
            go httpPost(cfg, &ar, ch)
        }

        switch <-ch {
        // some other cases ...
        case CALL_TIME_RAN_OUT:
            fmt.Printf("%d seconds have elapsed. Shutting down!", cfg.Duration)
            return
        }
    }
}

func httpPost(cfg AttackConfig, a *attackResponse, ch chan uint8) {
    // some code here to create HTTP client ...

    for {
        // some code to make HTTP call ...

        switch <-ch {
        case CALL_TIME_RAN_OUT:
            return
        }
    }
}
  • 写回答

1条回答 默认 最新

  • doubi9531 2017-03-27 03:30
    关注

    use package golang.org/x/net/context. Go 1.7 moves the golang.org/x/net/context package into the standard library as context. So just import context if you use version 1.7+.

    the usage is straightforward:

    package main
    
    import (
        "context"
        "fmt"
        "time"
    )
    
    func test(ctx context.Context) {
        t := time.Now()
    
        select {
        case <-time.After(1 * time.Second):
            fmt.Println("overslept")
        case <-ctx.Done():
        }
        fmt.Println("used:", time.Since(t))
    }
    
    func main() {
        ctx, _ := context.WithTimeout(context.Background(), 50*time.Millisecond)
        test(ctx)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)