Forked from AntoineAugusti/limitConcurrentGoroutines.go
Created
November 25, 2017 18:08
-
-
Save marlonfan/8a77eefe39e2af81f17704f0129c110f to your computer and use it in GitHub Desktop.
Revisions
-
AntoineAugusti revised this gist
Dec 9, 2015 . No changes.There are no files selected for viewing
-
AntoineAugusti revised this gist
Dec 9, 2015 . No changes.There are no files selected for viewing
-
AntoineAugusti revised this gist
Dec 9, 2015 . 1 changed file with 10 additions and 9 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,7 @@ package main import ( "flag" "fmt" "time" ) @@ -11,16 +12,16 @@ func DoWork() { } func main() { maxNbConcurrentGoroutines := flag.Int("maxNbConcurrentGoroutines", 5, "the number of goroutines that are allowed to run concurrently") nbJobs := flag.Int("nbJobs", 100, "the number of jobs that we need to do") flag.Parse() // Dummy channel to coordinate the number of concurrent goroutines. // This channel should be buffered otherwise we will be immediately blocked // when trying to fill it. concurrentGoroutines := make(chan struct{}, *maxNbConcurrentGoroutines) // Fill the dummy channel with maxNbConcurrentGoroutines empty struct. for i := 0; i < *maxNbConcurrentGoroutines; i++ { concurrentGoroutines <- struct{}{} } @@ -34,7 +35,7 @@ func main() { // Collect all the jobs, and since the job is finished, we can // release another spot for a goroutine. go func() { for i := 0; i < *nbJobs; i++ { <-done // Say that another goroutine can now start. concurrentGoroutines <- struct{}{} @@ -45,7 +46,7 @@ func main() { }() // Try to start nbJobs jobs for i := 1; i <= *nbJobs; i++ { fmt.Printf("ID: %v: waiting to launch!\n", i) // Try to receive from the concurrentGoroutines channel. When we have something, // it means we can start a new goroutine because another one finished. @@ -62,4 +63,4 @@ func main() { // Wait for all jobs to finish <-waitForAllJobs } -
AntoineAugusti revised this gist
Dec 3, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,7 +6,7 @@ import ( ) // Fake a long and difficult work. func DoWork() { time.Sleep(500 * time.Millisecond) } @@ -54,7 +54,7 @@ func main() { <-concurrentGoroutines fmt.Printf("ID: %v: it's my turn!\n", i) go func(id int) { DoWork() fmt.Printf("ID: %v: all done!\n", id) done <- true }(i) -
AntoineAugusti created this gist
Dec 3, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,65 @@ package main import ( "fmt" "time" ) // Fake a long and difficult work. func DoWork(id int) { time.Sleep(500 * time.Millisecond) } func main() { // The number of goroutines that are allowed to run concurrently maxNbConcurrentGoroutines := 5 // The number of jobs that we need to do nbJobs := 100 // Dummy channel to coordinate the number of concurrent goroutines. // This channel should be buffered otherwise we will be immediately blocked // when trying to fill it. concurrentGoroutines := make(chan struct{}, maxNbConcurrentGoroutines) // Fill the dummy channel with maxNbConcurrentGoroutines empty struct. for i := 0; i < maxNbConcurrentGoroutines; i++ { concurrentGoroutines <- struct{}{} } // The done channel indicates when a single goroutine has // finished its job. done := make(chan bool) // The waitForAllJobs channel allows the main program // to wait until we have indeed done all the jobs. waitForAllJobs := make(chan bool) // Collect all the jobs, and since the job is finished, we can // release another spot for a goroutine. go func() { for i := 0; i < nbJobs; i++ { <-done // Say that another goroutine can now start. concurrentGoroutines <- struct{}{} } // We have collected all the jobs, the program // can now terminate waitForAllJobs <- true }() // Try to start nbJobs jobs for i := 1; i <= nbJobs; i++ { fmt.Printf("ID: %v: waiting to launch!\n", i) // Try to receive from the concurrentGoroutines channel. When we have something, // it means we can start a new goroutine because another one finished. // Otherwise, it will block the execution until an execution // spot is available. <-concurrentGoroutines fmt.Printf("ID: %v: it's my turn!\n", i) go func(id int) { DoWork(id) fmt.Printf("ID: %v: all done!\n", id) done <- true }(i) } // Wait for all jobs to finish <-waitForAllJobs }