如何启动和停止功能

How to start and stop a function

我有一个使用两个不同 goroutine 的 go 函数 processingproduce 会将一些数据推送到通道中,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 执行此操作的正确方法是什么?

这里是如何使用上下文启动和停止一个函数,试试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 需要自己动手!
它需要一些 concurrent safe ID 或 map 或其他东西来跟踪你调用了多少函数,然后调用 cancel() 来停止它。