Code 1:
class thread_obj {
private:
static int instances;
bool run;
static mutex lock;
int threadno;
static map<int, thread> mapOfThreads;
public:
thread_obj():run(true)
{
lock.lock();
threadno = instances++;
thread th(thread_obj::thredfunc, this);
mapOfThreads[threadno] = move(th);
cout << "Thread no is " << threadno << endl;
lock.unlock();
}
static void thredfunc(thread_obj* ptr)
{
while (ptr->run)
{
std::this_thread::sleep_for(100ms);
}
}
void operator()()
{
while (run)
{
std::this_thread::sleep_for(100ms);
}
}
void stop()
{
run = false;
}
static int getTotalthreads()
{
return mapOfThreads.size();
}
~thread_obj()
{
lock.lock();
stop();
if (mapOfThreads[threadno].joinable())
mapOfThreads[threadno].join();
mapOfThreads.erase(threadno);
cout << "Destroyed " << threadno << endl;
lock.unlock();
}
};
int thread_obj::instances = 0;
mutex thread_obj::lock;
map<int, thread> thread_obj::mapOfThreads;
Code 2:
thread_obj():run(true)
{
lock.lock();
threadno = instances++;
thread th(thread_obj(), this);
mapOfThreads[threadno] = move(th);
cout << "Thread no is " << threadno << endl;
lock.unlock();
}
First code works fine, but changing constructor like given in code 2 gives error. In code 1 constructor create thread from static function.In code two constructor calls non static operator()
'std::invoke': no matching overloaded function found
Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...) noexcept(<expr>)'
What is the reason behind this? (This code is created to handle multiple threads.)
This line in the constructor is nonsense:
thread th(thread_obj(), this);
This will construct another thread_obj()
object, then try to invoke it in a new thread passing it the this
pointer, i.e. a thread_obj*
pointer. That would only work if the operator()
function took a thread_obj*
argument, but it doesn't.
I think what you're trying to do is run this->operator()()
in a new thread, so you would do that like this:
thread th(std::ref(*this));
This creates the new thread with a reference to *this
and then it will invoke it like (*this)()
, which will call operator()()
.
Alternatively, rename the operator()
function to give it a proper name, for example:
void thread_func()
{
while (run)
{
std::this_thread::sleep_for(100ms);
}
}
And then in the constructor pass a pointer-to-member-function to the std::thread
constructor, with this
as the object to call that member function on:
thread th(&thread_obj::thread_func, this);
There are hundreds of existing questions on stackoverflow explaining how to run a member function in a std::thread
.