+ 1
Doubt on Functor when used with thread
Hi Please find below code: https://sololearn.com/compiler-playground/c1BF2l1hn7Fg/?ref=app Why output is 200 and not 300? Does this mean thread object created calls overloaded operator() ? Why passing an object of functor class to thread function calls overloaded () operator? Any reason of this ? If it calls , then why function taking class object does not call overloaded () operator ? Additional query : why it result into compile time error when function signature takes object as call by value rather than call by reference?
17 Réponses
+ 3
☝️
I hope my changes to the code will help you better understand how it works.
Run it a dozen times to see how it works. You can also play with it by commenting out one line and documenting another line similar to it accordingly...😎:
https://sololearn.com/compiler-playground/ch96kv6FnzAn/?ref=app
+ 2
For a better understanding of the code, I have deleted everything superfluous and unnecessary.
The number of times you use the object, the number of times the loop works out.
In your case, twice, and in mine once:
class App
{
public:
void operator()()
{
for(int i=0;i<100;++i)
{
++cnt;
}
}
int get() {return cnt;}
private:
int cnt = 0;
};
int main()
{
App obj;
thread t1(ref(obj));
t1.join();
cout << obj.get();
return 0;
}
+ 2
Ketan Lalcheta
threads are executed.
functors passed to them using std::ref are called, and the state of the object is updated.
Here is another example, but this one accepts an int argument. your example is the same, only your functor don't accept any argument. But the process is the same.
Maybe you are mixing up constructors and functors? You instantiated your class in main.
You passed your functors by ref to the threads.
https://sololearn.com/compiler-playground/cHVXZWdWODWJ/?ref=app
+ 2
So I'm back and ready to provide my explanations... Apparently, you are just getting acquainted with the work of Thread.
I'm not a professional either, I'm just learning, so let's figure it out together.
This code demonstrates the execution of asynchronous, multithreaded operations.
This is necessary, for example, to simultaneously (conditionally) control two different characters in the game.
At first glance, this code should split the execution of the loop into two threads, which is why I tried to get from you why you decided that the output should be 300, I would most likely think that 100 because the loop will be executed only once, although the call operator will be called twice, because this is how this construction works.
That is, we must assume that if we want to write code for 200 million iterations, then we can write a cycle twice as small as necessary and create two threads, or, respectively, a 4 times smaller cycle and create 4 threads.
👇
+ 1
Ketan Lalcheta
you have to add
obj();
after instantiating App obj; in main, if you expect 300.
you only ran 2 threads. you did not run it in main.
I do not understand the purpose of testFunc.
Perhaps you mean:
void testFunc(App& obj)
{
obj();
}
This will also give you 300.
+ 1
Ketan Lalcheta it seems it does call the () operator.
void operator()()
{
cout<<"functor called!\n";
for(int i=0;i<100;++i)
{
m.lock();
++cnt;
m.unlock();
}
}
+ 1
Why so.. I got confused about this behavior
+ 1
maybe executing the thread is the same as calling obj()?
The same thing happens even without using thread.
App obj;
auto r = ref(obj);
r(); //x+=100
r(); //x+=100
+ 1
If it gets called when ref is passed , then why not getting called for free function taking class object as reference?
+ 1
Ketan Lalcheta I'm sorry, but I have to run. I'll explain later.
+ 1
Solo
instead of class based functors, the same thing can be done with functions and external variables.
I modified your code to test how it could be done. Instead of modifying an internal variable, we could modify an external variable instead.
https://sololearn.com/compiler-playground/cnkOpqcXpETo/?ref=app
+ 1
Bob_Li Yes, there is a wide range for creativity here, as this is a new level of development in programming.
And he still has to study and study.
For example, if you test this code, it turns out that it is much slower than if you did it using a regular loop, you need to at least achieve full synchronization of threads...😎
0
Let's forget about testFunc() for time being and ignore it for a time being.
Still why output is 200? We are not calling functor 2 times. Right? We just passed reference of functor class object to thread object. Does it call overloaded operator()? Is function call using object and passing reference of object a same thing?
0
Ketan Lalcheta I don't understand anything.
Explain it to me, stupid in Russian.
Why do you think the output should be 300?
In my opinion, everything is very clear...🤔
0
Write below line in overloaded operator () funcitons:
cout << "operator()\n";
Why it gets called ?
0
Ketan Lalcheta Well, how else?
Of course, it is called, therefore it is called the "call operator", and accordingly this object is a functor or literally a "Function Object" because it uses it in its constructor, and not an ordinary function.
0
I agree that it is call operator.
But does it mean that it gets called even through object is passed as reference?