Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 在终止线程之前,运行线程一定时间_Go - Fatal编程技术网

Go 在终止线程之前,运行线程一定时间

Go 在终止线程之前,运行线程一定时间,go,Go,如何运行10个线程,每个线程运行30秒,然后返回程序执行?例如,我想要 将生成10个线程并运行30秒 然后所有线程都被杀死 然后运行second()(即在所有线程完成执行之后) 到目前为止,我有以下几点,但是,当我这样做时,线程(显然)继续执行,CPU使用率在30秒后保持在100%: func main(){ for i := 0; i < 10; i++{ go thread() } time.Sleep(30 * time.Second)

如何运行10个线程,每个线程运行30秒,然后返回程序执行?例如,我想要

  • 将生成10个线程并运行30秒
  • 然后所有线程都被杀死
  • 然后运行
    second()
    (即在所有线程完成执行之后)
  • 到目前为止,我有以下几点,但是,当我这样做时,线程(显然)继续执行,CPU使用率在30秒后保持在100%:

    func main(){
        for i := 0; i < 10; i++{
            go thread()
        }
        time.Sleep(30 * time.Second)
        second()
    }
    
    func thread() {
        for {
            // Do stuff
        }
    }
    
    func main(){
    对于i:=0;i<10;i++{
    去线程()
    }
    时间。睡眠(30*时间。秒)
    第二()
    }
    func线程(){
    为了{
    //做事
    }
    }
    
    使用等待组和“完成”频道取消运行go例程,并在调用第二个
    之前同步它们的退出。这里可以阅读一些关于这个主题的非常酷的东西

    主程序包
    进口(
    “fmt”
    “同步”
    “时间”
    )
    func main(){
    //创建一个“完成”通道,用于向所有运行线程的go例程发送退出信号
    完成:=make(chan接口{})
    //在继续执行程序之前,创建一个等待组以同步所有go例程
    wg:=新建(sync.WaitGroup)
    对于i:=0;i<10;i++{
    //增量等待组
    工作组.添加(1)
    去线程(完成,工作组)
    }
    //zzzz。。。
    时间。睡眠(30*时间。秒)
    //关闭“完成”频道
    结束(完成)
    //等待所有go例程退出
    wg.Wait()
    //继续
    第二()
    }
    func线程(完成了chan接口{},wg*sync.WaitGroup){
    推迟工作组完成()
    工作:=真
    工作{
    //使用select语句执行工作,直到“完成”通道关闭
    挑选{
    案例使用等待组和“完成”频道取消运行go例程,并在调用
    second
    之前同步它们的退出。这里可以阅读一些关于该主题的非常酷的内容

    主程序包
    进口(
    “fmt”
    “同步”
    “时间”
    )
    func main(){
    //创建一个“完成”通道,用于向所有运行线程的go例程发送退出信号
    完成:=make(chan接口{})
    //在继续执行程序之前,创建一个等待组以同步所有go例程
    wg:=新建(sync.WaitGroup)
    对于i:=0;i<10;i++{
    //增量等待组
    工作组.添加(1)
    去线程(完成,工作组)
    }
    //zzzz。。。
    时间。睡眠(30*时间。秒)
    //关闭“完成”频道
    结束(完成)
    //等待所有go例程退出
    wg.Wait()
    //继续
    第二()
    }
    func线程(完成了chan接口{},wg*sync.WaitGroup){
    推迟工作组完成()
    工作:=真
    工作{
    //使用select语句执行工作,直到“完成”通道关闭
    挑选{
    
    case您可以使用Golang上下文。这是我学习Golang上下文时的一些代码

    package main
    
    import (
        "fmt"
        "log"
        "time"
    
        "golang.org/x/net/context"
    )
    
    func main() {
        someHandler()
    }
    
    func someHandler() {
        //Create a new context with a timeout duration of six seconds. You also get a cancel function you can call early. 
        //You can also have context end at a certain time, instead of a timeout
        ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(6))
    
        for i := 0; i < 5; i++ {
            go doStuff(ctx, i)
        }
    
        select {
        case <- ctx.Done():
            log.Println("Got a cancel request")
            return
        case <-time.After(time.Second * time.Duration(5)):
            //Here I'm actually ending it earlier than the timeout with cancel().
            log.Println("Timed out")
            cancel()
        }
    
    }
    
    func doStuff(ctx context.Context, num int) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("Done working")
                return
            default:
                fmt.Println("go", num, "working")
            }
            time.Sleep(time.Second)
        }
    }
    

    您可以使用Golang上下文。这是我学习Golang时的一些代码

    package main
    
    import (
        "fmt"
        "log"
        "time"
    
        "golang.org/x/net/context"
    )
    
    func main() {
        someHandler()
    }
    
    func someHandler() {
        //Create a new context with a timeout duration of six seconds. You also get a cancel function you can call early. 
        //You can also have context end at a certain time, instead of a timeout
        ctx, cancel := context.WithTimeout(context.Background(), time.Second*time.Duration(6))
    
        for i := 0; i < 5; i++ {
            go doStuff(ctx, i)
        }
    
        select {
        case <- ctx.Done():
            log.Println("Got a cancel request")
            return
        case <-time.After(time.Second * time.Duration(5)):
            //Here I'm actually ending it earlier than the timeout with cancel().
            log.Println("Timed out")
            cancel()
        }
    
    }
    
    func doStuff(ctx context.Context, num int) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("Done working")
                return
            default:
                fmt.Println("go", num, "working")
            }
            time.Sleep(time.Second)
        }
    }
    
    试试这个试试这个
    $ go run app.go 
    go 0 working
    go 4 working
    go 2 working
    go 3 working
    go 1 working
    go 1 working
    go 0 working
    go 4 working
    go 3 working
    go 2 working
    go 0 working
    go 4 working
    go 2 working
    go 1 working
    go 3 working
    go 4 working
    go 3 working
    go 0 working
    go 2 working
    go 1 working
    go 3 working
    go 4 working
    go 1 working
    go 0 working
    go 2 working
    2016/10/01 23:25:23 Timed out