代码的早期结束

时间:2017-10-04 03:55:53

标签: html go

在我的代码中,代码在执行所有任务之前执行。我必须更改我的代码,以便在结束之前执行所有任务吗?

package main

import (
"fmt"
"math/rand"
"time"
)

// run x tasks at random intervals
// - a task is a goroutine that runs for 2 seconds.
// - a task runs concurrently to other task
// - the interval between task is between 0 and 2 seconds

func main() {
// set x to the number of tasks
x := 4
// random numbers generation initialization
random := rand.New(rand.NewSource(1234))

for num := 0; num < x; num++ {
    // sleep for a random amount of milliseconds             before starting a new task
    duration := time.Millisecond *                 time.Duration(random.Intn(2000))
    time.Sleep(duration)

    // run a task
    go func() {
        // this is the work, expressed by sleeping for 2          seconds
        time.Sleep(2 * time.Second)
        fmt.Println("task done")
    }()
}
}

4 个答案:

答案 0 :(得分:1)

是的,因为@Laney提到这可以使用Waitgroups和channel来完成。请参阅下面的代码。

Waitgroups:

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

// run x tasks at random intervals
// - a task is a goroutine that runs for 2 seconds.
// - a task runs concurrently to other task
// - the interval between task is between 0 and 2 seconds

func main() {
    // set x to the number of tasks
    x := 4
    // random numbers generation initialization
    var wg sync.WaitGroup
    random := rand.New(rand.NewSource(1234))

    for num := 0; num < x; num++ {
        // sleep for a random amount of milliseconds             before starting a new task
        duration := time.Millisecond * time.Duration(random.Intn(2000))
        time.Sleep(duration)
        //
        wg.Add(1)
        // run a task
        go func() {
            // this is the work, expressed by sleeping for 2 seconds
            time.Sleep(2 * time.Second)
            fmt.Println("task done")
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println("All tasks done")
}

输出:

task done
task done
task done
task done
All tasks done

在操场上:https://play.golang.org/p/V-olyX9Qm8

使用频道:

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// run x tasks at random intervals
// - a task is a goroutine that runs for 2 seconds.
// - a task runs concurrently to other task
// - the interval between task is between 0 and 2 seconds

func main() {
    //Channel to indicate completion of a task, can be helpful in sending a result value also
    results := make(chan int)
    // set x to the number of tasks
    x := 4
    t := 0 //task tracker
    // random numbers generation initialization
    random := rand.New(rand.NewSource(1234))

    for num := 0; num < x; num++ {
        // sleep for a random amount of milliseconds             before starting a new task
        duration := time.Millisecond * time.Duration(random.Intn(2000))
        time.Sleep(duration)
        //

        // run a task
        go func() {
            // this is the work, expressed by sleeping for 2 seconds
            time.Sleep(2 * time.Second)
            fmt.Println("task done")
            results <- 1 //may be something possibly relevant to the task

        }()
    }
    //Iterate over the channel till the number of tasks
    for result := range results {
        fmt.Println("Got result", result)
        t++
        if t == x {
            close(results)
        }
    }
    fmt.Println("All tasks done")
}

输出:

task done
task done
Got result 1
Got result 1
task done
Got result 1
task done
Got result 1
All tasks done

游乐场:https://play.golang.org/p/yAFdDj5nhb

答案 1 :(得分:1)

在Go中,与大多数语言一样,当入口点sizeof(int)函数退出时,该过程将退出。

因为你正在产生一些goroutine,所以主要功能在goroutine完成之前结束,导致进程退出而不完成那些goroutines。

正如其他人所建议的那样,你想要阻止你的main()函数,直到完成所有goroutine,并且一些最常见的方法是使用信号量(sync.WaitGroup),或者渠道(go by example

答案 2 :(得分:0)

有很多选择。例如,您可以使用频道或sync.WaitGroup

答案 3 :(得分:0)

程序在主goroutine结束时结束。 你可以使用:

  • waitgroup - 它为所有任务完成时提供了非常方便的等待方式
  • 频道 - 从频道读取被阻止,直到新数据到达或频道关闭。
  • 天真的睡眠 - 仅用于示例目的