1

With most errors I often have some idea in what direction I need to head to it, but here I have no idea.

So let's start with the breakpoint itself:

enter image description here

There are relatively few times any interactions are mad using the thread library, here are all of them: The inclusion:

#include <thread>

The usage:

void evolve(double* bestN, double* bestP, double* bestM, double* bestQ, double* bestWinConstant) {

    std::thread threadArray[threadAmount];

    for (int i = 0; i < 100000; i++) {
        for (int t = 0; t < threadAmount; t++) {
            if (gameArrayInUse[t] == 0) {
                copyArray(gameArray[t], startArray);
                gameArrayInUse[t] = 1;
                threadArray[t] = std::thread(playGames, i, t);
                std::cout << "------------New Thread Spawned, No: " << t << std::endl;
                break;
            }
            if (t == threadAmount - 1) {
                t = -1;
            }
        }
    }

    for (int i = 0; i < threadAmount; i++)
    {
        std::cout << "JOIN THREADS--------------------------------------------------" << std::endl;
        threadArray[i].join();
    }
}

The error as seen in the console is (should be noted this changes every time):

Start of evolution on magnitude:1
------------New Thread Spawned, No: 0Completed:
0.000000%
------------New Thread Spawned, No: 1
Compl

Due to my lacking knowledge about this I apologise if you find the content I provide about my code lacking in certain areas, I would implore you to inform me via a comment so I can amend it.

Jonathan Woollett-light
  • 2,813
  • 5
  • 30
  • 58
  • 1
    Don't post pictures of code. Just post the code ... – Fantastic Mr Fox Sep 25 '17 at 23:45
  • Text is better presented as text and not images. This goes for all the images in your post. – Captain Giraffe Sep 25 '17 at 23:45
  • I just fixed these issues, was just thinking about that. – Jonathan Woollett-light Sep 25 '17 at 23:45
  • @JonathanWoollett-light Did you try to inspect the values of variables, via the debugger, **in your code**, at the time of the breakpoint was hit? Since the only place the `_Move_thread` might be called, in my opinion, would from all of the subsequent iterations of `i` (> 0), which would try to and reset all the threads in the array to new values, without waiting for them to complete. Why are you doing it? – Algirdas Preidžius Sep 25 '17 at 23:52
  • 1
    Perhaps you can look at using a proper thread pool than trying to roll your own? [This answer demonstrates one solution](https://stackoverflow.com/a/25684747/1270789) that could simplify your code. – Ken Y-N Sep 26 '17 at 00:02

2 Answers2

7

The "breakpoint" is actually triggered by _STD terminate(), one line above. (Especially when debugging native code, I find that it's a healthy habit to look at the line above the one that seems to have caused an error when it looks inexplicable.) Per the condition that wraps it, it's triggered when you move a thread on top of an existing thread that is running.

C++ does not allow you to overwrite running thread objects. Before running each iteration of your for(i) loop, you should ensure that every thread created in your for(t) loop has terminated. You can do that by calling thread::join. Alternatively, you can call thread::detach to let the thread run on its own without an object representing it, but you won't have any way to check for its completion.

You must also ensure that every thread has completed before the function returns, or else you'll get a similar error when the running thread objects are destroyed.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • 1
    `playGames()` perhaps ends with `gameArrayInUse[t] = 0; return;`, so there is a window between the `return` and the final thread termination code where the main thread can jump in and try to reuse `threadArray[t]`. – Ken Y-N Sep 26 '17 at 00:00
  • 2
    In that case, instead of maintaining that state, the program should use [`thread::joinable`](http://www.cplusplus.com/reference/thread/thread/joinable/) to check if the slot is available. (It's not available if `joinable()` returns true.) – zneak Sep 26 '17 at 00:03
  • @zneak Nevermind that didn't fix it, but I've fixed it now and you certainly pointed me in the right direction. – Jonathan Woollett-light Sep 26 '17 at 00:59
0

That code look very suspicious...

Inside your inner loop, you do:

 if (t == threadAmount - 1) {
     t = -1;
 }

Thus, t would be less than threadAmount on next iteration so it would loop again. But at that point, gameArrayInUse[t] is 1 so it look like your are wasting CPU doing useless stuff.

This is true assuming that the variable is only modified from that thread. If you modify it from another thread, then as you don't use any synchronisation primitive (like a mutex), then it is undefined behavior.

If you don't understand multithreading, then find some good books (for. ex. C++ Concurrency in action) and read them before writing code.

I guess that your playGames function modify the variable gameArrayInUse[t]. Assuming, this is the case, then another problem is that you start much more thread than you think as you are only waiting for tthreads to join at the end.

Another thing that is suspicious is the break inside the loop. Given that you break, you will try the same t on next iteration as t will restart at 0.

Thus it seems that the whole code make little sense and given that it is incomplete and we have no idea of what you are trying to do... we can almost only say that there are many issues with your code whatever it is expected to do.

Phil1970
  • 2,605
  • 2
  • 14
  • 15