如何启动和停止功能

时间:2019-10-07 12:37:11

标签: go goroutine

我有一个go函数processing,该函数使用两个不同的goroutine。 produce将一些数据推入通道,而consume将读取这些数据。这是一个示例:

type MyObject struct{
    ...
}

func processing() {
    var wg sync.WaitGroup
    dataChannel := make(chan MyObject, 5)

    wg.Add(2)

    go produce(wg, dataChannel)
    go consume(wg, dataChannel)

    wg.Wait()
}

func produce (wg *sync.WaitGroup, dataChannel chan MyObject){
    for{
        // Produce data in dataChannel
    }
}

func consume (wg *sync.WaitGroup, dataChannel chan MyObject){
    for{
        // Consume data from dataChannel
    }
}

我希望通过HTTP调用启动和停止processing函数。因此,我打算做一些事情,如下所示:

func main() {

    // echo instance
    e := echo.New()
    e.GET("/", startProcessing)
    e.Logger.Fatal(e.Start(":8099"))
}

func startProcessing(c echo.Context) error{

    command := c.QueryParam("command")

    if(command == "start"){
        processing()
    }else if(command == "stop"){
        if (/* ? processing is running ? */){
            /* ? stop processing process? */
        }
    }       
}

使用Go执行此操作的正确方法是什么?

1 个答案:

答案 0 :(得分:3)

此处介绍如何使用上下文启动和停止函数,请尝试this

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    var wg sync.WaitGroup
    dataChannel := make(chan MyObject, 5)
    wg.Add(2)
    go produce(ctx, &wg, dataChannel)
    go consume(&wg, dataChannel)

    time.Sleep(1 * time.Second)
    cancel() // cancel when we are finished consuming data

    wg.Wait()
}

func produce(ctx context.Context, wg *sync.WaitGroup, dataChannel chan MyObject) {
    defer wg.Done()
    i := 1
    for {
        select {
        case <-ctx.Done():
            close(dataChannel)
            return // returning not to leak the goroutine
        case dataChannel <- MyObject{i}:
            i++
            time.Sleep(250 * time.Millisecond)
        }
    }
}

func consume(wg *sync.WaitGroup, dataChannel chan MyObject) {
    defer wg.Done()
    for v := range dataChannel {
        fmt.Println(v)
    }
}

type MyObject struct {
    i int
}


对于HTTP,您需要自己动手!
它需要具有一些并发安全的 ID或映射,或一些东西来跟踪您调用了多少个函数,然后调用cancel()来停止它。