I'm testing c++11 threads with this code, but when creating the thread, I'm having the error no matching function for call to 'std::thread::thread()'.
It's like if there was something wrong with the function I'm giving to std::thread ctr, but I don't see how it's wrong. It is incompleted, but it looks right to me:
Header:
#ifndef CONNECTION_H
#define CONNECTION_H
#include <thread>
#include <mysql++.h>
class Connection
{
public:
Connection(std::string mysqlUser, std::string mysqlPassword);
~Connection();
private:
std::string mysqlUser;
std::string mysqlPassword;
std::string mysqlIP;
int mysqlPort;
mysqlpp::Connection mysqlConnection;
std::thread connectionThread;
void threadLoop();
};
#endif // CONNECTION_H
Source:
#include "connection.h"
Connection::Connection(std::string mysqlUser, std::string mysqlPassword)
{
this->mysqlUser = mysqlUser;
this->mysqlPassword = mysqlPassword;
this->mysqlIP = "localhost"; //default
this->mysqlPort = 3306; //default
//Launch thread
std::thread connectionThread(threadLoop);
}
Connection::~Connection(){
mysqlConnection.disconnect();
}
void Connection::threadLoop(){
//Connect to mySQL database
mysqlConnection = new mysqlpp::Connection(false);
if(mysqlConnection.connect(NULL, mysqlIP.c_str(), mysqlUser.c_str(), mysqlPassword.c_str(), mysqlPort)){
std::string consulta = "SELECT * FROM 'Coordinates'";
mysqlpp::Query query = mysqlConnection.query(consulta);
mysqlpp::StoreQueryResult res = query.store();
query.reset();
}
while(true){
// Stuff
}
}
The problem is that threadLoop
is a member function, but there is no object for it to be applied to. Just guessing:
std::thread connectionThread(&Connection::threadLoop, this);
But that's just the syntactic issue; there's a logic problem, too: that line creates a local object of type std::thread
that goes away when the function returns. Its destructor will call std::terminate()
because the thread has not been joined. Most likely, this was supposed to attach a thread to the connectionThread
member. To do that:
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
Your code has two problems:
std::thread
constructorstd::thread
before it is joined with the main thread.For the first problem, as Pete Becker suggests, you need to provide the object on which the function will be called, because the constructor for std::thread
has no other way to know it. Assuming that you want to call function threadLoop()
on the Connection
object you are constructing, you can do this:
//Launch thread
std::thread connectionThread(threadLoop, this);
Internally, the constructor will call this->threadLoop()
(where this
is the Connection*
parameter it received, not the std::thread
itself, of course). And you will be fine.
The second problem is that your std::thread
is destroyed immediately after starting, without having joined it to the main thread: this will call terminate()
, which is not a good thing. Once again, Pete suggests a good alternative. Replace the above code with this:
// Launch thread
std::thread thr(threadLoop, this);
std::swap(thr, connectionThread);
The situation before this code is as follows:
std::thread
object, connectionThread
, which does not really represent a threadAfter executing the first line of code:
connectionThread
std::thread
object thr
, which will be destroyed at the end of the Connection
constructor, causing a call to terminate()
because it is never joined to the main thread.Fortunately, the second line of code comes to the rescue. After executing it:
std::thread
, thr
, which can be safely destroyed because it does not represent a real thread (so it is not joinable)connectionThread
, an object that will not be destroyed as long as the Connection
object exists.Now, the problem is that you want to join connectionThread
to the main thread before it is destroyed, but you also want to avoid blocking the main thread. The right time to do this join is the latest possible time: when connectionThread
is about to be destroyed. And this happens at the destructor of Connection
. So we'll add a line to this destructor, this way:
Connection::~Connection(){
mysqlConnection.disconnect();
connectionThread.join(); // Now connectionThread can be safely destroyed
}
Besides, this is the safest place to call join()
, because it ensures that you will never destroy an unjoined connectionThread
. This is RAII in action; if you are not familiar with the concept of RAII (or RIIA, as it is sometimes called), you can find a lot of information about this very important concept in the web, including this site.
All this put together: creating a Connection
object will create a new thread; in this thread, a new database connection will be established and a query will be executed, while the main thread remains free for whatever other use (for instance, managing the GUI). When the Connection
object is finally destroyed, the main thread will wait for the additional thread to finish (if necessary) and then normal execution will continue. I hope this is what you wanted to accomplish with your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With