0

This is a class:

#include <thread>
#include <vector>

class A {
  private:
    void render(int, std::vector<std::vector<int>>&) {
        //do stuff
    };

    void renderSegment() {
        int var1 = 1;
        std::vector<std::vector<int>> var2;

        std::thread t(????);
        t.join();
    };
};

Here are some attempts:

std::thread t([this, var1, &var2] {renderSegment(var1, var2);});
std::thread t(renderSegment, var1, std::ref(var2));
std::thread t(&A::renderSegment, var1, std::ref(var2));
std::thread t(&renderSegment, this, var1, std::ref(var2));

I want to call render(var1, var2) in the function renderSegment(). I've look at a couple of questons, like this

Start thread with member function

and this

C++11 multithreading with class member function

but nothing seems to work. Even when it looks like it should work, the compiler tells me that that I'm attempting to reference a deleted function std::thread::thread(const std::thread &).

I'm using C++17 and MVSC, for better or for worse. I haven't enabled any kind of special flags, but I was unable to find any that would explicitly enable multithreading in the program itself (there is one for multithreaded compilation).

How do I make it work?

EDIT: Here is longer, but real code:

Renderer.h

#include <glm/vec2.hpp>
#include <glm/vec3.hpp>

#include <complex>
#include <map>
#include <vector>

class State;

class Renderer {
public:
    void renderScene();
    Renderer(State& state);

private:
    State& m_state;

    void renderMandelbrot(int power);
    double mandelbrot(std::complex<double> c, int power);
    void renderSegment(
        int segmentStart,
        int segmentSize,
        int power,
        std::vector<std::vector<glm::vec3>>& colours);
};

Renderer.cpp

#include "Renderer.h"

#include "State.h"

#include <algorithm>
#include <thread>
#include <time.h>

void Renderer::renderScene() {
    renderMandelbrot(m_state.m_power);
}

Renderer::Renderer(State& state) :
    m_state(state) {

    std::srand(time(NULL));
    m_state.m_threadCount = std::thread::hardware_concurrency();
}

void Renderer::renderMandelbrot(int power) {
    std::vector<std::vector<glm::vec3>> colours;
    colours.resize(m_state.m_height);
    for (int i = 0; i < m_state.m_height; ++i) {
        colours[i].resize(m_state.m_width);
    }

    int segmentSize = m_state.m_height / m_state.m_threadCount;
    int segmentStart = 0;

    std::vector<std::thread> threads;

    for (int k = 0; k < m_state.m_threadCount - 1; ++k, segmentStart += segmentSize) {
        std::thread t = std::thread(&Renderer::renderMandelbrot, this,
            segmentStart,
            segmentStart + segmentSize,
            power,
            std::ref(colours));
        threads.push_back(t);
    }
    std::thread t = std::thread(&Renderer::renderMandelbrot, this,
            segmentStart,
            m_state.m_height,
            power,
            std::ref(colours));
        threads.push_back(t);

    for (auto& thread : threads) {
        thread.join();
    }
}

void Renderer::renderSegment(
    int segmentStart,
    int segmentEnd,
    int power,
    std::vector<std::vector<glm::vec3>>& colours) {

    for (int j = segmentStart; j < segmentEnd; ++j) {
        for (int i = 0; i < m_state.m_width; ++i) {
            colours[j][i] = glm::vec3(1.0f, 1.0f, 1.0f);
        }
    }
}

State is pretty much just a bunch of values, so I omitted the code for it.

Karlovsky120
  • 6,212
  • 8
  • 41
  • 94
  • @Karlovsky120 I've actually answered a question like this. See my answer: https://stackoverflow.com/a/61377194/13375552 – Azam Bham May 01 '20 at 18:00
  • Well I must be missing something, but I don't know why. If you can give me an example that should work with this particular case, it will either work and I'll feel extremely stupid, or I'll get an error that might tell us more about what's going on. – Karlovsky120 May 01 '20 at 18:00
  • @AzamBham Your answer works great until I have to pass the reference, then it tells me 'qualifiers dropped in binding reference' and I don't know what to do with that. – Karlovsky120 May 01 '20 at 18:05
  • @FrançoisAndrieux I tried what you wrote, but it still complains about attempting to reference a deleted function I mentioned in my question. – Karlovsky120 May 01 '20 at 18:07
  • @Karlovsky120 I think you tried `std::thread t(&A::render, *this, var1, std::ref(var2));` instead of `std::thread t(&A::render, this, var1, std::ref(var2));`. – François Andrieux May 01 '20 at 18:13
  • If the linked question does not solve your problem, then the problem is caused by something not included in the question. The linked question is a duplicate of this question as it was asked. Consider posting a [MCVE]. – François Andrieux May 01 '20 at 18:15
  • I tried both, both giving me the same error. I'll try to expand the example. – Karlovsky120 May 01 '20 at 18:15
  • Can you make "void render ()" static ? If yes, it could help. – Sébastien Bémelmans May 01 '20 at 18:16
  • @Karlovsky120 Please read this article : [MCVE]. The example is not compilable and not verifiable. You almost had it right the first time when you made a small code sample, except for the fact that it didn't actually reproduce the problem. – François Andrieux May 01 '20 at 18:22
  • @SébastienBémelmans I could, but then Renderer as an object doesn't really make any sense. – Karlovsky120 May 01 '20 at 18:23
  • @Karlovsky120 `push_back(t)` is trying to copy your thread into the vector. Use `push_back(std::move(t))`. – François Andrieux May 01 '20 at 18:24
  • That was it. It's always something stupid. Always. – Karlovsky120 May 01 '20 at 18:30

0 Answers0