Put all database operations in a specific thread using Qt - c++

I have a console application where after a timeout signal, a 2D matrix (15*1200) should be parsed element-by element and inserted to a database. Since the operation is time-consuming, I perform the insertion in a new thread using QConcurrent::run.
However, due to timeout signals, several threads may start before one finished, so multiple accesses to the database may occur.
As a solution, I was trying to buffer all database operations in a specific thread, in other words, assign a specific thread to the database class, but do not know how to do so.

Your problem is a classical concurrent data analysis problem. Have you tried using std::mutex? Here's how you use it:
You create some variable std::mutex (mutex = mutual exclusion) that's accessible by all the relevant threads.
std::mutex myLock;
and then, let's say that the function that processes the data looks like this:
void processData(const Data& myData)
{
ProcessedData d = parseData();
insertToDatabase(d);
}
Now from what I understand, you're afraid that multiple threads will call insertToDatabase(d) simultaneously. Now to solve this issue, simply do the following:
void processData(const Data& myData)
{
ProcessedData d = parseData();
myLock.lock();
insertToDatabase(d);
myLock.unlock();
}
Now with this, if another thread tries to access the same function, it will block until another all other threads are finished. So threads are mutually excluded from accessing the call together.
More about this:
Caveats:
This mutex object must be the same one that all the threads see, otherwise this is useless. So either make it global (bad idea, but will work), or put it in a the class that will do the calls.
Mutex objects are non-copyable. So if you include them in a class, you should either make the mutex object a pointer, or you should reimplement the copy constructor of that class to prevent copying that mutex, or make your class noncopyable using delete:
class MyClass
{
//... stuff
MyClass(const MyClass& src) = delete;
//... other stuff
};
There are way more fancier ways to use std::mutex, including std::lock_guard and std::unique_lock, which take ownership of the mutex and do the lock for you. This are good to use if you know that the call insertToDatabase(d); could throw an exception. In that case, using only the code I wrote will not unlock the mutex, and the program will reach a deadlock.
In the example I provided, here's how you use lock_guard:
void processData(const Data& myData)
{
ProcessedData d = parseData();
std::lock_guard<std::mutex> guard(myLock);
insertToDatabase(d);
//it will unlock automatically at the end of this function, when the object "guard" is destroyed
}
Be aware that calling lock() twice by the same thread has undefined behavior.
Everything I did above is C++11.
If you're going to deal with multiple threads, I recommend that you start reading about data management with multiple threads. This is a good book.
If you insist on using Qt stuff, here's the same thing from Qt... QMutex.

Related

C++ return function lock_guard

I have the resource "resource" that wrapped in shared_ptr, and I want to access it from other threads.
When I do this:
// foo.h
class Foo{
public:
std::shared_ptr<Setup> GetSomeThing();
void SetSomeThing();
private:
std::shared_ptr<Setup> resource;
std::mutex lock;
}
//Foo.cpp
std::shared_ptr<Setup> Foo::GetSomeThing()
{
std::lock_guard<std::mutex> lock (mutex);
return resource;
}
void Foo::SetSomeThing()
{
std::lock_guard<std::mutex> lock (mutex);
resource = ...;
}
is it all ok?
When will be created a return object and when will be destroyed the lock? Is there something about it in the documentation?
Thank you!
This answer assumes (for clarity) that the two lines:
std::lock_guard<std::mutex> lock (mutex);
are both replaced with
std::lock_guard<std::mutex> guard (lock);
If multiple threads access a single instance of std::shared_ptr<> without synchronization and any of those call non-const members then a data race occurs.
That means you must ensure synchronization between SetSomeThing() and GetSomething().
Introducing a std::mutex and using std::lock_guard<> in the way proposed will do that. The returned copy will have been constructed before the destructor of guard is called.
Do note that it's about the same instance. The copy returned by GetSomeThing() has sufficient internal synchronization to ensure it can be accessed (non-const and even destructed) without synchronizing other instances.
However none of that prevents data races on any shared Setup object (part-)owned by the std::shared_ptr<Setup>. If all access to Setup is read-only then multiple threads can access it but if any threads write to the shared data a data race occurs (without further synchronization not shown in the question).
An object like Setup in a simple application may be constructed and initialized before multiple threads are launched and destructed when all but the main-thread have terminated. In that specific case no further synchronization would be required and even the provided lock is superfluous.
Here's a non-normative reference:
http://en.cppreference.com/w/cpp/memory/shared_ptr
Refer to the last paragraph of the opening description.
Footnote: Changing application "setup" can be far harder than simply ensuring that data races don't occur on the attributes. Threads may need to pend adopting changes or 'abandon' activity. For example consider a graphical program in which the screen resolution is changed during a 'draw' step. Should it finish the draw and produce a canvas that is too large/small or dump the part-drawn canvas and adopt the new resolution? Has the setup even been acquired in such a way that the draw will produce something consistent with 'before' or 'after' and not some nonsensical (possibly crashing) hybrid?

Mutex as class member using pthreads

I have three classes, let's call them A, B and HardwareDriver. There is one instance of each of the classes. a and b run in two different threads. They both access the Hardware via an instance of HardwareDriver. Something like:
Class A {
... };
Class B {
... };
Class HardwareDriver {
public:
int accessHardware();
};
A a;
B b;
HardwareDriver hd;
pthread_t aThread;
pthread_t bThread;
main() {
pthread_create(&aThread, NULL, &A::startA, &a);
pthread_create(&bThread, NULL, &B::startB, &b);
while (...) { };
return 0;
}
The hardware can't be accessed by a and b at the same time, so I need to protect the code with a mutex. I'm new to multithreading but intuitively I would lock the mutex in the method of A and B right before it requests the hardware access by calling the method hd.accessHardware().
Now I'm wondering if it's possible, to perform the locking in hd.accessHardware() for more encapsulation. Would this still be thread safe?
Yes you can have a mutex in your HardwareDriver class and have a critical section inside your class method. It would still be safe. Just remember that if you copy the object, you will also have a copy of mutex.
I would lock the mutex in the method of A and B right before it requests the hardware access by calling the method hd.accessHardware().
This creates a risk of forgetting to lock that mutex prior to calling hd.accessHardware().
Now I'm wondering if it's possible, to perform the locking in hd.accessHardware() for more encapsulation. Would this still be thread safe?
That removes the risk of forgetting to lock that mutex and makes your API harder to misuse. And that would still be thread safe.
When doing multithread programming in C/C++ you should ensure that data that is accessed by any of your thread for WRITING is locked when you do any READ or WRITE operation, you can leave lockfree READONLY datas.
The lock operations must have the smaller scope possibile, if TWO objects access a single resource you need a SINGLE semaphore/mutex, using two will expose you to dangerous deadlocks.
So, in your example you should add a mutex inside the HardwareDriver class and lock/unlock it everytime you read/write any class data.
You do not need to lock local data (stack allocated local variables) and you do not need locking on reentrant methods.
Since you are writing C++ and we are in 2017, I suppose you could use, and suggest you to use std::thread and std::mutex instead of pthread directly. In Linux the C++ native thread support is a tiny wrapper over pthreads so the overhead of using them is negligible also in embedded targets.

Should a critical section or mutex be really member variable or when should it be?

I have seen code where mutex or critical section is declared as member variable of the class to make it thread safe something like the following.
class ThreadSafeClass
{
public:
ThreadSafeClass() { x = new int; }
~ThreadSafeClass() {};
void reallocate()
{
std::lock_guard<std::mutex> lock(m);
delete x;
x = new int;
}
int * x;
std::mutex m;
};
But doesn't that make it thread safe only if the same object was being shared by multiple threads? In other words, if each thread was creating its own instance of this class, they will be very much independent and its member variables will never conflict with each other and synchronization will not even be needed in that case!?
It appears to me that defining the mutex as member variable really reduces synchronization to the events when the same object is being shared by multiple threads. It doesn't really make the class any thread safer if each thread has its own copy of the class (for example if the class were to access other global objects). Is this a correct assessment?
If you can guarantee that any given object will only be accessed by one thread then a mutex is an unnecessary expense. It however must be well documented on the class's contract to prevent misuse.
PS: new and delete have their own synchronization mechanisms, so even without a lock they will create contention.
EDIT: The more you keep threads independent from each other the better (because it eliminates the need for locks). However, if your class will work heavily with a shared resource (e.g. database, file, socket, memory, etc ...) then having a per-thread instance is of little advantage so you might as well share an object between threads. Real independence is achieved by having different threads work with separate memory locations or resources.
If you will have potentially long waits on your locks, then it might be a good idea to have a single instance running in its own thread and take "jobs" from a synchronized queue.

pthread mutex lock and unlock per variable

I'm wondering what the best practice for locking and unlocking mutexes for variables withing an object that is shared between threads.
This is what I have been doing and seems to work just fine so far, just wondering if this is excessive or not though:
class sharedobject
{
private:
bool m_Var1;
pthread_mutex_t var1mutex;
public:
sharedobject()
{
var1mutex = PTHREAD_MUTEX_INITIALIZER;
}
bool GetVar1()
{
pthread_mutex_lock(&var1mutex);
bool temp = m_Var1;
pthread_mutex_unlock(&var1mutex);
return temp;
}
void SetVar1(bool status)
{
pthread_mutex_lock(&var1mutex);
m_Var1 = status;
pthread_mutex_unlock(&var1mutex);
}
};
this isn't my actual code, but it shows how i am using mutexes for every variable that is shared in an object between threads. The reason i don't have a mutex for the entire object is because one thread might take seconds to complete an operation on part of the object, while another thread checks the status of the object, and again another thread gets data from the object
my question is, is it a good practice to create a mutex for every variable within an object that is accessed between threads, then lock and unlock that variable when it is read or written to?
I use trylock for variables i'm checking the status to (so i don't create extra threads while the variable is being processed, and don't make the program wait to get a lock)
I haven't had a lot of experience working with threading. I would like the make the program thread safe, but it also needs to perform as best as possible.
if the members you're protecting are read-write, and may be accessed at any time by more than one thread, then what you're doing is not excessive - it's necessary.
If you can prove that a member will not change (is immutable) then there is no need to protect it with a mutex.
Many people prefer multi-threaded solutions where each thread has an immutable copy of data rather than those in which many threads access the same copy. This eliminates the need for memory barriers and very often improves execution times and code safety.
Your mileage may vary.

C++ Singleton in multithread

I am new to multi thread programming, yet I am studying a big project by someone else. In the code he has a singleton class and it has some public member variable and a member mutex. He used this singleton in different threads like:
singleton::instance()->mutex.lock();
singleton::instance()->value = getval();
singleton::instance()->mutex.release();
Is this the safe way to do it?
If not what is the proper way of read/write the value in singleton?
No it is not safe to do so.
The problem is that the mutex is handed out to the user. There is no guarantee that this lock will be released. For example, what happens if getval() would throw an exception ?
The proper way to do so would be to embed mutex use inside the API of your singleton. For example:
void singleton::setvalue(int val) { // example supposing value is an int
std::lock_guard<std::mutex> mylck (mutex);
value = val;
}
In this example, a local std::lock_guard is used. This object locks the mutex and unlocks it on destruction. This makes sure that in any case the mutex will be unlocked, whenever function returns and even if an exception would be thrown.
Note: If all you are doing is getting a variable like return variable; then it is safe to do even without the lock.
About the code. Assuming the lock is implemented correctly then it is safe to do anything before release is called