Running a constant number of goroutines The Next CEO of Stack OverflowUnderstanding goroutinesWhat is the neatest idiom for producer/consumer in Go?Why does adding concurrency slow down this golang code?Different results for N>1 goroutines (on N>1 Cpu:s). Why?How do goroutines work? (or: goroutines and OS threads relation)MySQL - Get the total amount of concurrent events for a given date rangeWorker pool for a potentially recursive task (i.e., each job can queue other jobs)How to synchronize multiple goroutines to the termination of a selected goroutine (ie. Thread.join())Self-Synchronizing Goroutines end up with DeadlockHow to discard printouts when running tests

Why does freezing point matter when picking cooler ice packs?

Direct Implications Between USA and UK in Event of No-Deal Brexit

What happens if you break a law in another country outside of that country?

Is a linearly independent set whose span is dense a Schauder basis?

How to coordinate airplane tickets?

Shortening a title without changing its meaning

Oldie but Goldie

A hang glider, sudden unexpected lift to 25,000 feet altitude, what could do this?

Raspberry pi 3 B with Ubuntu 18.04 server arm64: what pi version

Why doesn't Shulchan Aruch include the laws of destroying fruit trees?

How to unfasten electrical subpanel attached with ramset

Why do we say “un seul M” and not “une seule M” even though M is a “consonne”?

Would a grinding machine be a simple and workable propulsion system for an interplanetary spacecraft?

How can the PCs determine if an item is a phylactery?

Simplify trigonometric expression using trigonometric identities

Car headlights in a world without electricity

Can you teleport closer to a creature you are Frightened of?

Read/write a pipe-delimited file line by line with some simple text manipulation

How to compactly explain secondary and tertiary characters without resorting to stereotypes?

Finitely generated matrix groups whose eigenvalues are all algebraic

What steps are necessary to read a Modern SSD in Medieval Europe?

How to show a landlord what we have in savings?

Does int main() need a declaration on C++?

Upgrading From a 9 Speed Sora Derailleur?



Running a constant number of goroutines



The Next CEO of Stack OverflowUnderstanding goroutinesWhat is the neatest idiom for producer/consumer in Go?Why does adding concurrency slow down this golang code?Different results for N>1 goroutines (on N>1 Cpu:s). Why?How do goroutines work? (or: goroutines and OS threads relation)MySQL - Get the total amount of concurrent events for a given date rangeWorker pool for a potentially recursive task (i.e., each job can queue other jobs)How to synchronize multiple goroutines to the termination of a selected goroutine (ie. Thread.join())Self-Synchronizing Goroutines end up with DeadlockHow to discard printouts when running tests










0















I'm not completely sure what's going on here so it's hard to generalize my question, but I'm going to try my very best.



In a video from a few years ago Matt Parker dared his viewers to find a power of two, which does not contain any digits which are a power of two. (For example, 2^16 = 65536. None of these digits individually are a power of two). Recently I got into learning Go and I thought it would be a nice introductory exercise to get used to the language.



I created this pretty quickly and then I decided to try to make it concurrent to make full use of my quad core processor. This is where things went downhill.



The goal here is to run a constant amount of goroutines each of which processes a different batch of numbers. I implemented the program like so:



package main

import (
"log"
"math/big"
"runtime"
)

//The maximum amount of goroutines
const routineAmt int = 3

//The amount of numbers for each routine to check
const rangeSize int64 = 5000

//The current start of the range to start checking
var rangeIndex int64 = 0

func main()
//loop forever
for
//if we have less routines running than the maximum
if runtime.NumGoroutine() < routineAmt
c := make(chan bool)
// start a new one to check the next range:
go checkRange(rangeIndex, rangeIndex+rangeSize, c)
// wait for the signal that the values have been copied to the function, so that we can increment them safely:
<-c
close(c)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize




// Function to check a range of powers of two, whether they contain any power-of-two-digits
func checkRange(from, to int64, c chan bool)
c <- true // signal to the main routine that the parameter values have been copied

// Loop through the range for powers of two, which do not contain any power-of-two-digits
for i := from; i < to; i++
num := big.NewInt(2)
num.Exp(num, big.NewInt(i), nil)
if !hasStringPowerOfTwo(num.String())
log.Println("Found 2 ^", i)


log.Printf("Checked range %d-%dn", from, to)


// Function to check if a string contains any number which is a power of two
func hasStringPowerOfTwo(input string) bool
powersOfTwo := [4]rune'1', '2', '4', '8'
for _, char := range input
if runeInArray(char, powersOfTwo)
return true


return false


// Function to check if a list of runes contains a certain rune
func runeInArray(a rune, list [4]rune) bool
for _, b := range list
if b == a
return true


return false



After waiting about 15 minutes or so, the program still did not finish a single go routine (that is, I did not see log.Printf("Checked range %d-%dn", from, to) in the console)



I tried lowering the range size to 5, which resulted in a few goroutines to be completed but it abruptly stopped at the range 2840-2845. I thought this might be due to the numbers getting bigger and the calculation taking more time, but this doesn't make sense as the stop is very abrupt. If this were the case I would expect the slowdown to be at least a little gradual.










share|improve this question
























  • If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

    – Adrian
    Mar 21 at 20:25






  • 1





    Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

    – JimB
    Mar 21 at 20:28











  • Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

    – Kush Patel
    Mar 22 at 0:33











  • you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

    – Reza Nasiri
    Mar 22 at 1:08















0















I'm not completely sure what's going on here so it's hard to generalize my question, but I'm going to try my very best.



In a video from a few years ago Matt Parker dared his viewers to find a power of two, which does not contain any digits which are a power of two. (For example, 2^16 = 65536. None of these digits individually are a power of two). Recently I got into learning Go and I thought it would be a nice introductory exercise to get used to the language.



I created this pretty quickly and then I decided to try to make it concurrent to make full use of my quad core processor. This is where things went downhill.



The goal here is to run a constant amount of goroutines each of which processes a different batch of numbers. I implemented the program like so:



package main

import (
"log"
"math/big"
"runtime"
)

//The maximum amount of goroutines
const routineAmt int = 3

//The amount of numbers for each routine to check
const rangeSize int64 = 5000

//The current start of the range to start checking
var rangeIndex int64 = 0

func main()
//loop forever
for
//if we have less routines running than the maximum
if runtime.NumGoroutine() < routineAmt
c := make(chan bool)
// start a new one to check the next range:
go checkRange(rangeIndex, rangeIndex+rangeSize, c)
// wait for the signal that the values have been copied to the function, so that we can increment them safely:
<-c
close(c)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize




// Function to check a range of powers of two, whether they contain any power-of-two-digits
func checkRange(from, to int64, c chan bool)
c <- true // signal to the main routine that the parameter values have been copied

// Loop through the range for powers of two, which do not contain any power-of-two-digits
for i := from; i < to; i++
num := big.NewInt(2)
num.Exp(num, big.NewInt(i), nil)
if !hasStringPowerOfTwo(num.String())
log.Println("Found 2 ^", i)


log.Printf("Checked range %d-%dn", from, to)


// Function to check if a string contains any number which is a power of two
func hasStringPowerOfTwo(input string) bool
powersOfTwo := [4]rune'1', '2', '4', '8'
for _, char := range input
if runeInArray(char, powersOfTwo)
return true


return false


// Function to check if a list of runes contains a certain rune
func runeInArray(a rune, list [4]rune) bool
for _, b := range list
if b == a
return true


return false



After waiting about 15 minutes or so, the program still did not finish a single go routine (that is, I did not see log.Printf("Checked range %d-%dn", from, to) in the console)



I tried lowering the range size to 5, which resulted in a few goroutines to be completed but it abruptly stopped at the range 2840-2845. I thought this might be due to the numbers getting bigger and the calculation taking more time, but this doesn't make sense as the stop is very abrupt. If this were the case I would expect the slowdown to be at least a little gradual.










share|improve this question
























  • If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

    – Adrian
    Mar 21 at 20:25






  • 1





    Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

    – JimB
    Mar 21 at 20:28











  • Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

    – Kush Patel
    Mar 22 at 0:33











  • you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

    – Reza Nasiri
    Mar 22 at 1:08













0












0








0








I'm not completely sure what's going on here so it's hard to generalize my question, but I'm going to try my very best.



In a video from a few years ago Matt Parker dared his viewers to find a power of two, which does not contain any digits which are a power of two. (For example, 2^16 = 65536. None of these digits individually are a power of two). Recently I got into learning Go and I thought it would be a nice introductory exercise to get used to the language.



I created this pretty quickly and then I decided to try to make it concurrent to make full use of my quad core processor. This is where things went downhill.



The goal here is to run a constant amount of goroutines each of which processes a different batch of numbers. I implemented the program like so:



package main

import (
"log"
"math/big"
"runtime"
)

//The maximum amount of goroutines
const routineAmt int = 3

//The amount of numbers for each routine to check
const rangeSize int64 = 5000

//The current start of the range to start checking
var rangeIndex int64 = 0

func main()
//loop forever
for
//if we have less routines running than the maximum
if runtime.NumGoroutine() < routineAmt
c := make(chan bool)
// start a new one to check the next range:
go checkRange(rangeIndex, rangeIndex+rangeSize, c)
// wait for the signal that the values have been copied to the function, so that we can increment them safely:
<-c
close(c)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize




// Function to check a range of powers of two, whether they contain any power-of-two-digits
func checkRange(from, to int64, c chan bool)
c <- true // signal to the main routine that the parameter values have been copied

// Loop through the range for powers of two, which do not contain any power-of-two-digits
for i := from; i < to; i++
num := big.NewInt(2)
num.Exp(num, big.NewInt(i), nil)
if !hasStringPowerOfTwo(num.String())
log.Println("Found 2 ^", i)


log.Printf("Checked range %d-%dn", from, to)


// Function to check if a string contains any number which is a power of two
func hasStringPowerOfTwo(input string) bool
powersOfTwo := [4]rune'1', '2', '4', '8'
for _, char := range input
if runeInArray(char, powersOfTwo)
return true


return false


// Function to check if a list of runes contains a certain rune
func runeInArray(a rune, list [4]rune) bool
for _, b := range list
if b == a
return true


return false



After waiting about 15 minutes or so, the program still did not finish a single go routine (that is, I did not see log.Printf("Checked range %d-%dn", from, to) in the console)



I tried lowering the range size to 5, which resulted in a few goroutines to be completed but it abruptly stopped at the range 2840-2845. I thought this might be due to the numbers getting bigger and the calculation taking more time, but this doesn't make sense as the stop is very abrupt. If this were the case I would expect the slowdown to be at least a little gradual.










share|improve this question
















I'm not completely sure what's going on here so it's hard to generalize my question, but I'm going to try my very best.



In a video from a few years ago Matt Parker dared his viewers to find a power of two, which does not contain any digits which are a power of two. (For example, 2^16 = 65536. None of these digits individually are a power of two). Recently I got into learning Go and I thought it would be a nice introductory exercise to get used to the language.



I created this pretty quickly and then I decided to try to make it concurrent to make full use of my quad core processor. This is where things went downhill.



The goal here is to run a constant amount of goroutines each of which processes a different batch of numbers. I implemented the program like so:



package main

import (
"log"
"math/big"
"runtime"
)

//The maximum amount of goroutines
const routineAmt int = 3

//The amount of numbers for each routine to check
const rangeSize int64 = 5000

//The current start of the range to start checking
var rangeIndex int64 = 0

func main()
//loop forever
for
//if we have less routines running than the maximum
if runtime.NumGoroutine() < routineAmt
c := make(chan bool)
// start a new one to check the next range:
go checkRange(rangeIndex, rangeIndex+rangeSize, c)
// wait for the signal that the values have been copied to the function, so that we can increment them safely:
<-c
close(c)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize




// Function to check a range of powers of two, whether they contain any power-of-two-digits
func checkRange(from, to int64, c chan bool)
c <- true // signal to the main routine that the parameter values have been copied

// Loop through the range for powers of two, which do not contain any power-of-two-digits
for i := from; i < to; i++
num := big.NewInt(2)
num.Exp(num, big.NewInt(i), nil)
if !hasStringPowerOfTwo(num.String())
log.Println("Found 2 ^", i)


log.Printf("Checked range %d-%dn", from, to)


// Function to check if a string contains any number which is a power of two
func hasStringPowerOfTwo(input string) bool
powersOfTwo := [4]rune'1', '2', '4', '8'
for _, char := range input
if runeInArray(char, powersOfTwo)
return true


return false


// Function to check if a list of runes contains a certain rune
func runeInArray(a rune, list [4]rune) bool
for _, b := range list
if b == a
return true


return false



After waiting about 15 minutes or so, the program still did not finish a single go routine (that is, I did not see log.Printf("Checked range %d-%dn", from, to) in the console)



I tried lowering the range size to 5, which resulted in a few goroutines to be completed but it abruptly stopped at the range 2840-2845. I thought this might be due to the numbers getting bigger and the calculation taking more time, but this doesn't make sense as the stop is very abrupt. If this were the case I would expect the slowdown to be at least a little gradual.







go concurrency






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 21 at 20:38









Flimzy

40.2k1367101




40.2k1367101










asked Mar 21 at 19:52









David CDavid C

85




85












  • If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

    – Adrian
    Mar 21 at 20:25






  • 1





    Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

    – JimB
    Mar 21 at 20:28











  • Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

    – Kush Patel
    Mar 22 at 0:33











  • you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

    – Reza Nasiri
    Mar 22 at 1:08

















  • If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

    – Adrian
    Mar 21 at 20:25






  • 1





    Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

    – JimB
    Mar 21 at 20:28











  • Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

    – Kush Patel
    Mar 22 at 0:33











  • you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

    – Reza Nasiri
    Mar 22 at 1:08
















If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

– Adrian
Mar 21 at 20:25





If you issue a SIGQUIT to a running Go program, it will issue stack traces for all running goroutines, which might be helpful. When it seems to have slowed excessively, send a SIGQUIT and see what it's up to.

– Adrian
Mar 21 at 20:25




1




1





Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

– JimB
Mar 21 at 20:28





Don't use runtime.NumGoroutine in your program logic. Either start a known number of goroutines, or dispatch them as needed. There are dozens of resources on concurrency patterns to choose from.

– JimB
Mar 21 at 20:28













Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

– Kush Patel
Mar 22 at 0:33





Try using a WaitGroup golang.org/pkg/sync/#example_WaitGroup

– Kush Patel
Mar 22 at 0:33













you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

– Reza Nasiri
Mar 22 at 1:08





you can also use a [semaphore] (godoc.org/golang.org/x/sync/semaphore) to limit the number of goroutines

– Reza Nasiri
Mar 22 at 1:08












1 Answer
1






active

oldest

votes


















0














You should not be using a for loop with a check on runtime.NumGoroutine to make sure you don't have too many routines running, because the loop will prevent the goruntime to schedule your routines properly, it will slowdown the whole thing.



Instead, you should use a buffered channel which signals when a routine is done, so that you can start a new one.



I have adjusted your main function and checkRange function:



func main() 
var done = make(chan struct, routineAmt)
//loop forever
for i := 0; i < routineAmt; i++
// start a new one to check the next range:
go checkRange(done, rangeIndex, rangeIndex+rangeSize)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize


for range done
// start a new one to check the next range:
go checkRange(done, rangeIndex, rangeIndex+rangeSize)
// increment the rangeIndex for the next routine which will start:
rangeIndex += rangeSize



// Function to check a range of powers of two, whether they contain any power-of-two-digits
func checkRange(done chan<- struct, from, to int64)
// Loop through the range for powers of two, which do not contain any power-of-two-digits
for i := from; i < to; i++
num := big.NewInt(2)
num.Exp(num, big.NewInt(i), nil)
if !hasStringPowerOfTwo(num.String())
log.Println("Found 2 ^", i)


log.Printf("Checked range %d-%dn", from, to)

// let our main go routine know we're done with this one
done <- struct






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55288303%2frunning-a-constant-number-of-goroutines%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You should not be using a for loop with a check on runtime.NumGoroutine to make sure you don't have too many routines running, because the loop will prevent the goruntime to schedule your routines properly, it will slowdown the whole thing.



    Instead, you should use a buffered channel which signals when a routine is done, so that you can start a new one.



    I have adjusted your main function and checkRange function:



    func main() 
    var done = make(chan struct, routineAmt)
    //loop forever
    for i := 0; i < routineAmt; i++
    // start a new one to check the next range:
    go checkRange(done, rangeIndex, rangeIndex+rangeSize)
    // increment the rangeIndex for the next routine which will start:
    rangeIndex += rangeSize


    for range done
    // start a new one to check the next range:
    go checkRange(done, rangeIndex, rangeIndex+rangeSize)
    // increment the rangeIndex for the next routine which will start:
    rangeIndex += rangeSize



    // Function to check a range of powers of two, whether they contain any power-of-two-digits
    func checkRange(done chan<- struct, from, to int64)
    // Loop through the range for powers of two, which do not contain any power-of-two-digits
    for i := from; i < to; i++
    num := big.NewInt(2)
    num.Exp(num, big.NewInt(i), nil)
    if !hasStringPowerOfTwo(num.String())
    log.Println("Found 2 ^", i)


    log.Printf("Checked range %d-%dn", from, to)

    // let our main go routine know we're done with this one
    done <- struct






    share|improve this answer



























      0














      You should not be using a for loop with a check on runtime.NumGoroutine to make sure you don't have too many routines running, because the loop will prevent the goruntime to schedule your routines properly, it will slowdown the whole thing.



      Instead, you should use a buffered channel which signals when a routine is done, so that you can start a new one.



      I have adjusted your main function and checkRange function:



      func main() 
      var done = make(chan struct, routineAmt)
      //loop forever
      for i := 0; i < routineAmt; i++
      // start a new one to check the next range:
      go checkRange(done, rangeIndex, rangeIndex+rangeSize)
      // increment the rangeIndex for the next routine which will start:
      rangeIndex += rangeSize


      for range done
      // start a new one to check the next range:
      go checkRange(done, rangeIndex, rangeIndex+rangeSize)
      // increment the rangeIndex for the next routine which will start:
      rangeIndex += rangeSize



      // Function to check a range of powers of two, whether they contain any power-of-two-digits
      func checkRange(done chan<- struct, from, to int64)
      // Loop through the range for powers of two, which do not contain any power-of-two-digits
      for i := from; i < to; i++
      num := big.NewInt(2)
      num.Exp(num, big.NewInt(i), nil)
      if !hasStringPowerOfTwo(num.String())
      log.Println("Found 2 ^", i)


      log.Printf("Checked range %d-%dn", from, to)

      // let our main go routine know we're done with this one
      done <- struct






      share|improve this answer

























        0












        0








        0







        You should not be using a for loop with a check on runtime.NumGoroutine to make sure you don't have too many routines running, because the loop will prevent the goruntime to schedule your routines properly, it will slowdown the whole thing.



        Instead, you should use a buffered channel which signals when a routine is done, so that you can start a new one.



        I have adjusted your main function and checkRange function:



        func main() 
        var done = make(chan struct, routineAmt)
        //loop forever
        for i := 0; i < routineAmt; i++
        // start a new one to check the next range:
        go checkRange(done, rangeIndex, rangeIndex+rangeSize)
        // increment the rangeIndex for the next routine which will start:
        rangeIndex += rangeSize


        for range done
        // start a new one to check the next range:
        go checkRange(done, rangeIndex, rangeIndex+rangeSize)
        // increment the rangeIndex for the next routine which will start:
        rangeIndex += rangeSize



        // Function to check a range of powers of two, whether they contain any power-of-two-digits
        func checkRange(done chan<- struct, from, to int64)
        // Loop through the range for powers of two, which do not contain any power-of-two-digits
        for i := from; i < to; i++
        num := big.NewInt(2)
        num.Exp(num, big.NewInt(i), nil)
        if !hasStringPowerOfTwo(num.String())
        log.Println("Found 2 ^", i)


        log.Printf("Checked range %d-%dn", from, to)

        // let our main go routine know we're done with this one
        done <- struct






        share|improve this answer













        You should not be using a for loop with a check on runtime.NumGoroutine to make sure you don't have too many routines running, because the loop will prevent the goruntime to schedule your routines properly, it will slowdown the whole thing.



        Instead, you should use a buffered channel which signals when a routine is done, so that you can start a new one.



        I have adjusted your main function and checkRange function:



        func main() 
        var done = make(chan struct, routineAmt)
        //loop forever
        for i := 0; i < routineAmt; i++
        // start a new one to check the next range:
        go checkRange(done, rangeIndex, rangeIndex+rangeSize)
        // increment the rangeIndex for the next routine which will start:
        rangeIndex += rangeSize


        for range done
        // start a new one to check the next range:
        go checkRange(done, rangeIndex, rangeIndex+rangeSize)
        // increment the rangeIndex for the next routine which will start:
        rangeIndex += rangeSize



        // Function to check a range of powers of two, whether they contain any power-of-two-digits
        func checkRange(done chan<- struct, from, to int64)
        // Loop through the range for powers of two, which do not contain any power-of-two-digits
        for i := from; i < to; i++
        num := big.NewInt(2)
        num.Exp(num, big.NewInt(i), nil)
        if !hasStringPowerOfTwo(num.String())
        log.Println("Found 2 ^", i)


        log.Printf("Checked range %d-%dn", from, to)

        // let our main go routine know we're done with this one
        done <- struct







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 22 at 2:54









        François P.François P.

        2,085716




        2,085716





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55288303%2frunning-a-constant-number-of-goroutines%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript