user4137741
user4137741

Reputation:

Array of Threads

I'm trying to create an array of threads and give each of them a function but not working

Reader *readers = new Reader[10];

thread *ts = new thread[10];

for (int i = 0; i<10; i++){
    readers[i].setAll(q, "t" + i);
    ts[i] = thread(readers[i].run); //Error: "cannot be referenced. its a deleted function"
}

Run function:

void Reader::run(){
    log(this->source);
    log.log("starting");

    while (flag){
        this->m = this->q.get(this->source);
        log.log("retrieved " + m.toString());
        if (m.getData().compare("stop") && m.getTarget().compare(this->source))
        {
            log.log("stopping");
            this->setFlag(false);//stop the current thread if the message is "stop"
        }
        else{
            if (!m.getTarget().compare(source)){//if the message isnt from the current thread then put the message back
                string dest = m.getSource();
                m.setSource(this->source);
                log.log("putting back [" + dest + "->" + m.getTarget() + ":" + " " + m.getData() + "] as " + m.toString());
                q.put(m);
                log.log("done putting back " + m.toString());
            }
        }
    }
}

I'm actually trying to do the following code:

thread t0(readers[0].run);
thread t1(readers[1].run);
etc...

but it also gives me the same error seen below:

The error message

Upvotes: 1

Views: 1664

Answers (2)

Richard Hodges
Richard Hodges

Reputation: 69882

If you're using c++11 you might want to take advantage of the nice memory management and binding features:

(edit: updated code in response to comments)

#include <iostream>
#include <thread>
#include <memory>
#include <vector>

using namespace std;

struct runner
{
    void run() {
        cout << "hello" << endl;
    }
};

int main()
{
    vector<unique_ptr<runner>> runners;
    for(size_t i = 0 ; i < 10 ; ++i) {
        runners.emplace_back(new runner);
    }

    vector<thread> threads;
    for(const auto& r : runners) {
        threads.emplace_back(&runner::run, r.get());
    }

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

   return 0;
}

Upvotes: 1

Mike Seymour
Mike Seymour

Reputation: 254461

While readers[i].run looks like it should bind an object to a member function to make a callable object, sadly it doesn't. Instead, you need to pass a pointer to the member function and a pointer (or reference wrapper) to the object as separate arguments:

thread(&Reader::run, &readers[i]);    // or std::ref(readers[i])

or you might find it nicer to wrap the function call in a lambda:

thread([=]{readers[i].run();})

Upvotes: 0

Related Questions