Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

correct use of functor for C++ STL thread

I'm having some difficulty understanding the correct usage of a functional object as a thread routine in C++ STL. From my understanding, one of the benefits of a functor is that the object instance can maintain state. There are times when I want one or more threads to run some routine and compute some result. I then query those results from the objects after I have joined the threads. I'm trying to do the same with C++ STL threads and running into some problems. It appears the problem stems from the fact that the C++ STL thread makes a copy of my object and thus I'm not sure how I'm supposed to go about inspecting the results when I join the threads. Here's a snippet of the code:

#include <iostream>
#include <thread>

using namespace std;

class Worker
{
public:
    Worker() : _value(0)
    {
    }

    void operator()(unsigned int value);

    unsigned int get_value() {return this->_value;}

private:
    unsigned int _value;
};

void Worker::operator()(unsigned int value)
{
    this->_value = value;
}

int main()
{
    Worker worker;
    thread thread(worker, 13);
    thread.join();
    unsigned int value = worker.get_value();
    cout << "value: " << value << endl;
}

The above example is just a simple repro of the problem I'm running into. I would expect worker.get_value() to return 13 yet it's returning zero. How do I go about instantiating an object with state, having a thread run a routine in that object, and then query the state of that object after the thread has completed?

Thanks, Nick

like image 347
nickdu Avatar asked Mar 20 '17 01:03

nickdu


People also ask

What is the use of functor?

A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.

What is a functor in C?

In other words, a functor is any object that can be used with () in the manner of a function. This includes normal functions, pointers to functions, and class objects for which the () operator (function call operator) is overloaded, i.e., classes for which the function operator()() is defined.

How do you pass a functor to a function in C++?

You cannot pass a functor as a function pointer into a function that takes a function pointer, even if the functor has the same arguments and return value as the function pointer. Similarly, if a function expects a functor, you cannot pass in a function pointer.

What is multithreading C ++ 11?

Multithreading in C++ C++ 11 did away with all that and gave us std::thread. The thread classes and related functions are defined in the thread header file. std::thread is the thread class that represents a single thread in C++.


2 Answers

When you pass by value you make a copy. So you can pass by reference through reference wrapper:

thread thread(std::ref(worker), 13);

or pass by pointer:

thread thread(&worker, 13);

in both cases you have to make sure that object lifetime is long enough.

like image 88
Slava Avatar answered Sep 28 '22 10:09

Slava


Don't make a copy, but instead bind the thread to a reference:

thread thread(std::ref(worker), 13);
//            ^^^^^^^^
like image 36
Kerrek SB Avatar answered Sep 28 '22 10:09

Kerrek SB