注意进入 Go 循环

我已经编写了代码来获取CPU内核的使用百分比。如果一个内核的 CPU 使用率低于 50%,我将运行压力测试代码,以将使用率百分比提高到高于 50%。我必须为所有CPU内核应用此策略。


这是我的完整代码:


package main


import (

    "fmt"

    "io/ioutil"

    "net/http"

    "os"

    "strconv"

    "strings"

    "time"

    "github.com/dhoomakethu/stress/utils"

    strip "github.com/grokify/html-strip-tags-go"

)


func main() {

    url := "http://localhost:8080/getCPU"

    resp := Get(url)

    //remove htlm tag

    stripped := strip.StripTags(resp)

    s := strings.Split(stripped, "%")

    var j []int

    for i := 0; i < len(s)-1; i++ {

        number, _ := strconv.Atoi(s[i])

        if number < 50 {

            j = append(j, i)

        }

    }

    fmt.Println(j)

    sampleInterval := 100 * time.Millisecond

    cpuload := 1.0

    duration := 300.0

    for a := 0; a < len(j)/2; a++ {

        cpucore := j[a]

        runCpuLoader(sampleInterval, cpuload, duration, cpucore)

    }

}


//GET

func Get(url string) string {

    response, err := http.Get(url)

    if err != nil {

        fmt.Printf("%s", err)

        os.Exit(1)

    } else {

        defer response.Body.Close()

        contents, err := ioutil.ReadAll(response.Body)

        if err != nil {

            fmt.Printf("%s", err)

            os.Exit(1)

        }

        return string(contents)

    }

    return ""

}


// stress cpu

func runCpuLoader(sampleInterval time.Duration, cpuload float64, duration float64, cpu int)   {

    controller := utils.NewCpuLoadController(sampleInterval, cpuload)

    monitor := utils.NewCpuLoadMonitor(float64(cpu), sampleInterval)


    actuator := utils.NewCpuLoadGenerator(controller, monitor, time.Duration(duration))

    utils.StartCpuLoadController(controller)

    utils.StartCpuMonitor(monitor)


    utils.RunCpuLoader(actuator)

    utils.StopCpuLoadController(controller)

    utils.StopCpuMonitor(monitor)


}

在这段代码中


for a := 0; a < len(j)/2; a++ {

    cpucore := j[a]

    runCpuLoader(sampleInterval, cpuload, duration, cpucore)

   }


}

我希望代码并发运行压力测试增加 CPU 使用率的百分比。但该函数的持续时间为 5 分钟,因此它不能作为并发运行。runCpuLoader(sampleInterval, cpuload, duration, cpucore)


呼啦一阵风
浏览 85回答 1
1回答

德玛西亚99

您应该完成围棋之旅,并特别关注围棋例程以及查看等待组。我将在这里简要介绍适用的概念。关键字go在Go中,同时运行函数非常容易。鉴于以下代码,我只需要在 前面添加前缀,使其与程序的其余部分同时运行。goblockingCodefunc blockingCode() {&nbsp; &nbsp; time.Sleep(time.Second)&nbsp; &nbsp; fmt.Println("finishing blocking")}func main() {&nbsp; &nbsp; fmt.Println("starting main")&nbsp; &nbsp; go blockingCode()&nbsp; &nbsp; fmt.Println("finishing main")}你会注意到关于这一点的几件事:如果我删除了前缀,该函数将被阻止,您将看到所有三个打印语句,最后两个比第一个打印语句晚一秒(去游乐场)。go如果我重新添加前缀,该函数不会阻塞,但您不会看到 print 语句。这是因为主函数(主 go 例程)在完成之前终止。这就是等待组发挥作用的地方。gofmt.Println("finishing blocking")blockingCodeWaitGroup要等待多个戈鲁丁完成,我们可以使用一个等待组。https://gobyexample.com/waitgroups。将等待组视为原子计数器,其中调用阻塞直到计数器为 0。生成 go 例程时,会递增计数器 (),在完成 go 例程时,会取消递增计数器 ()。下面是支持等待组的代码。去游乐场wg.Waitwg.Addwg.Donefunc blockingCode(wg *sync.WaitGroup) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; time.Sleep(time.Second)&nbsp; &nbsp; fmt.Println("finishing blocking")}func main() {&nbsp; &nbsp; wg := sync.WaitGroup{}&nbsp; &nbsp; fmt.Println("starting main")&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go blockingCode(&wg)&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; fmt.Println("finishing main")}现在,这会产生与我们上面看到的完全相同的行为 - 该函数将阻塞,您将看到所有三个print语句,最后两个比第一个延迟一秒钟打印 - 那么为什么我们首先将其并发?不同之处在于,我们现在可以同时运行许多事情,而不是按顺序运行很多事情。在这种情况下,我们没有看到并发的好处的原因是因为我们只同时做一件事。让我们调整示例以运行多次。您会注意到,脚本运行所需的时间几乎相同,即使我们调用的 blockCode 需要整整一秒钟才能运行,三次,如果我们删除关键字和等待组,我们会看到此代码至少需要三秒钟才能运行 go Playground。blockingCodegofunc blockingCode(wg *sync.WaitGroup) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; time.Sleep(time.Second)&nbsp; &nbsp; fmt.Println("finishing blocking")}func main() {&nbsp; &nbsp; wg := sync.WaitGroup{}&nbsp; &nbsp; fmt.Println("starting main")&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go blockingCode(&wg)&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go blockingCode(&wg)&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; go blockingCode(&wg)&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; fmt.Println("finishing main")}您的示例您选择如何处理并发行为很大程度上取决于应用程序的细节,但是像这样的东西应该实现我在这里提供的并发概念,并允许您与加载程序同时运行监视器。func main() {&nbsp; &nbsp; // ...&nbsp; &nbsp; wg := sync.WaitGroup{}&nbsp; &nbsp; for a := 0; a < len(j)/2; a++ {&nbsp; &nbsp; &nbsp; &nbsp; cpucore := j[a]&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go runCpuLoader(&wg, sampleInterval, cpuload, duration, cpucore)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}func runCpuLoader(wg *sync.WaitGroup, sampleInterval time.Duration, cpuload float64, duration float64, cpu int) {&nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; // ...}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go