Reputation: 2801
How do I run 10 threads, for 30 seconds each, and then return to the program execution? For example, I want
second()
to run (i.e. after all threads have finished executing)So far I have the following however, when I do this, the threads (obviously) keep executing and CPU usage remains at 100% after 30s:
func main(){
for i := 0; i < 10; i++{
go thread()
}
time.Sleep(30 * time.Second)
second()
}
func thread() {
for {
// Do stuff
}
}
Upvotes: 1
Views: 2024
Reputation: 860
You could use Golang context. Here's some of my code when I was learning it.
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)
}
}
Outputs:
$ 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
Upvotes: 2
Reputation: 2295
Use a wait group and a "done" channel to cancel running go routines and and synchronize their exits before calling second
. Some really cool stuff on the topic can be read here https://blog.golang.org/pipelines.
package main
import (
"fmt"
"sync"
"time"
)
func main() {
//create a "done" channel that will be used to signal to all go routines running thread to quit
done := make(chan interface{})
//create a wait group to sync all go routines before continuing program execution
wg := new(sync.WaitGroup)
for i := 0; i < 10; i++ {
//increment waitgroup
wg.Add(1)
go thread(done, wg)
}
//zzzz...
time.Sleep(30 * time.Second)
//close the done channel
close(done)
//wait for all go routines to quit
wg.Wait()
//move on
second()
}
func thread(done chan interface{}, wg *sync.WaitGroup) {
defer wg.Done()
working := true
for working {
//use a select statement to do work until done channel is closed
select {
case <-done:
//end the loop
working = false
default:
fmt.Println("doing work...")
}
}
}
func second() {
fmt.Println("program complete")
}
Upvotes: 1