qboomerang
qboomerang

Reputation: 2211

vectors and threading in C++

I would like to request for comments/ideas on how to resolve a vector and threading issue that is becoming a bit convoluted. I have researched the issue and have not found a working solution.

The intention is to have 5 person objects (stored in a vector) and then call each of their method to read a book concurrently (hence the threads). The read function contains a never ending loop.

I have the following code(simplified) set up:

class Book{
    private:
         // some data                                                                                   
    public:
        // some functions                                                                              
};

class Person{
    private:
        // some data vars                                                                              
        int id;
        Book abook;
    public:
        // some functions                                                                              
        Person(int index=0);  // constructor                                                           
        void readBook();
};

int main(void){

    vector<Person>PersonsVector;
    vector<thread> threads;
    int num_of_persons = 5;

    for(int i=0; i<num_of_persons; i++){
        PersonsVector.push(Person(i));  //create different people       
        threads.push_back(thread(PersonsVector[i].readBook)); //read book in thread        
    }

   // wait for threads to finnish or kill threads                                                 
    for(auto& thread: threads) 
        threads.join();
}

My issue is really in how to call the readBook() function and push this to a thread

 threads.push_back(thread(PersonsVector[i].readBook)); //read book in thread

Various variations for example these below lead to errors...

 threads.push_back(thread(&PersonsVector[i].Person::readBook, this));             
 threads.push_back(thread(&Person::PersonsVector[i].Person::readBook, this));

Any ideas how I could resolve this issue?

Upvotes: 2

Views: 1621

Answers (2)

underscore_d
underscore_d

Reputation: 6795

A pointer-to-method must be called using a combination of a pointer specifying the class and method + an instance of said class on which to invoke said method.

This... thing:

&Person::PersonsVector[i].Person::readBook

actually says...

  • Get me the class Person,
  • then a vector within an unspecified instance of Person, which does not contain any such vector...
  • then an index i within that invalid vector,
  • then somehow get the constructor of that instance,
  • then somehow get a method readBook() from within that constructor.

See the problem? That's invalid syntax in so many varied ways.

The correct syntaxes are as follows:

  • For the pointer-to-method: &Person::readBook
  • For the instance: PersonsVector[i]

...and you need to give these to std::thread via some mechanism that will bundle the pointer-to-method and instance and make them callable for you - such as a lambda, std::bind, etc. - something like this:

std::thread theThread{
    [] // not sure which capture is needed... :/
    {
        (someInstance.*pointerToMethod)(the, args);
        // i.e.
        (PersonsVector[i].*readBook)();
    }
};

Upvotes: 2

anycmon
anycmon

Reputation: 23

You can use a lambda: threads.push_back(thread([&PersonsVector[i]])(Person& p){ p.readBook(); });

Upvotes: 0

Related Questions