Callbacks to virtual functions - c++

I am doing some work with threading on an embedded platform. This platform provides a Thread class, and it has a start method that takes a function pointer, like this:
void do_in_parallel() {
// Some stuff to do in a new thread
}
Thread my_thread;
my_thread.start(do_in_parallel);
The problem is there is no way to pass parameters in.1 I want to solve this by creating an abstract class, call it Thread2, that extends Thread (or it could just have a Thread as instance data).
Thread2 would have a pure virtual function void run() and the goal was to pass that to Thread::start(void*()), except I soon learned that member function pointers have a different type and can't be used like this. I could make run() static, but then I still can't have more than one instance, defeating the whole purpose (not to mention you can't have a virtual static function).
Are there any workarounds that wouldn't involve changing the original Thread class (considering it's a library that I'm stuck with as-is)?
1. Global variables are a usable workaround in many cases, except when instantiating more than one thread from the same function pointer. I can't come up with a way to avoid race conditions in that case.

Write a global thread pool.
It maintains a queue of tasks. These tasks can have state.
Whe you add a task to the queue, you can choose to also request it get a thread immediately. Or you can wait for threads in the pool to be finished what they are doing.
The threads in the pool are created by the provided Thread class, and they get their marching instructions from the pool. For the most part, they should pop tasks, do them, then wait on another task being ready.
If waiting isn't permitted, you could still have some global thread manager that stores state for the threads.
The pool/manager returns the equivalent of a future<T> augmented with whatever features you want. Code that provides tasks interacts with the task through that object instead of the embedded Thread type.

A simple wrapper can be written if locking is permitted
void start(Thread& t, void (*fn)(void*), void* p)
{
static std::mutex mtx; // or any other mutex
static void* sp;
static void (*sfn)(void*);
mtx.lock();
sp = p;
sfn = fn;
t.start([]{
auto p = sp;
auto fn = sfn;
mtx.unlock();
fn(p);
});
}
This is obviously not going to scale well, all thread creations goes through the same lock, but its likely enough.
Note this is exception-unsafe, but I assume that is fine in embedded systems.
With the wrapper in place
template<typename C>
void start(Thread& t, C& c)
{
start(t, [](void* p){
(*(C*)p)();
}, &c);
}
Which allows any callable to be used. This particular implementation places the responsibility of managing the callable's lifetime on the caller.

You can create your own threaded dispatching mechanism (producer-consumer queue) built around the platform specific thread.
I assume that you have the equivalent facilities of mutex and conditional variables/signalling mechanism for the target platform.
Create a thread safe queue that can accept function objects.
The run method creates a thread and waits on the queue.
The calling thread can call post()/invoke() method that simply insert a function object to the queue.
The function object can have the necessary arguments passed to the caller thread.

Related

Put all database operations in a specific thread using Qt

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.

std::thread constructor with no parameter

According to cppreference.com, the
std::thread constructor with no parameter means:
Creates new thread object which does not represent a thread.
My questions are:
Why do we need this constructor? And if we create a thread using this constructor, how can we "assign" a thread function later?
Why don't we have a "run(function_address)" method so that when constructed with no parameter, we can specify a function to "run" for that thread.
Or, we can construct a thread with a callable parameter (function, functors, etc.) but call a "run()" method to actually execute the thread later. Why is std::thread not designed in this way?
Your question suggests there might be some confusion and it would be helpful to clearly separate the ideas of a thread of execution from the std::thread type, and to separate both from the idea of a "thread function".
A thread of execution represents a flow of control through your program, probably corresponding to an OS thread managed by the kernel.
An object of the type std::thread can be associated with a thread of execution, or it can be "empty" and not refer to any thread of execution.
There is no such concept as a "thread function" in standard C++. Any function can be run in a new thread of execution by passing it to the constructor of a std::thread object.
why do we need this constructor?
To construct the empty state that doesn't refer to a thread of execution. You might want to have a member variable of a class that is a std::thread, but not want to associate it with a thread of execution right away. So you default construct it, and then later launch a new thread of execution and associate it with the std::thread member variable. Or you might want to do:
std::thread t;
if (some_condition) {
t = std::thread{ func1, arg1 };
}
else {
auto result = some_calculation();
t = std::thread{ func2, arg2, result };
}
The default constructor allows the object t to be created without launching a new thread of execution until needed.
And if we create a thread using this constructor, how can we "assign" a thread function later?
You "assign" using "assignment" :-)
But you don't assign a "thread function" to it, that is not what std::thread is for. You assign another std::thread to it:
std::thread t;
std::thread t2{ func, args };
t = std::move(t2);
Think in terms of creating a new thread of execution not "assigning a thread function" to something. You're not just assigning a function, that's what std::function would be used for. You are requesting the runtime to create a new thread of execution, which will be managed by a std::thread object.
Why don't we have a "run(function_address)" method so that when constructed with no parameter, we can specify a function to "run" for that thread.
Because you don't need it. You start new threads of execution by constructing a std::thread object with arguments. If you want that thread of execution to be associated with an existing object then you can do that by move-assigning or swapping.
Or, we can construct a thread with a callable parameter(function, functors, etc.) but call a "run()" method to actually execute the thread later. Why std::thread is not designed in this way?
Why should it be designed that way?
The std::thread type is for managing a thread of execution not holding a callable object for later use. If you want to create a callable object that can be later run on a new thread of execution there are lots of ways to do that in C++ (using a lambda expression, or std::bind, or std::function, or std::packaged_task, or a custom functor type). The job of std::thread is to manage a thread of execution not to hold onto a callable object until you want to call it.
The default constructor is provided such that an "empty" thread object can be created. Not all thread objects will be associated with a thread of execution at the time of construction of said object. Consider when the thread is a member of some type and that type has a default constructor. Consider another case that the thread type has no concept of a "suspended" thread, i.e. it can't be created in a suspended state.
The thread type doesn't have a "run" method of some sort since the one of the original design decisions (IIRC) was to have a "strong" association between the thread object and the thread of execution. Allowing threads to be "moved" makes that intent clearer (in my opinion). Hence moving an instance of a thread object to an "empty" object is clearer than attempting to "run" a thread.
It is conceivable that you can create a wrapper class of some sort that offers the "run" method, but I think this may be a narrower use case, and that can be solved given the API of the std::thread class.
The default constructor gives you then possibility to create array of threads:
thread my_threads[4];
for (int i=0; i<4; i++)
{
thread temp(func,...);
my_threads[i]=move(temp);
}
the thread created with default costructor "become" a "real" thread with the move costructor.
You can use thread with standard container if you need/like.
EDIT: Maybe lets firsts comment on the very last part:
3.2 Why std::thread is not designed in this way?
I don't know why exactly (there are surely advantages and disatvantages - see Jonathan Wakely's answer for a more details about the rational behind it), but it seems that c++11 std::thread is modelled much closer to pthreads than e.g. QT's or Java's QThread/Thread classes, which might be the source of your confusion.
As to the rest of your questions:
1.1 why do we need this constructor?
You might want to create a std::thread variable but don't directly start a thread (e.g. a class member variable or an element of a static array, es shown by alangab). It's not much different to an std::fstream that can be created without a filename.
1.2 And if we create a thread using this constructor, how can we "assign" a thread function later?
For example:
std::thread myThread;
// some other code
myThread = std::thread(foo());
Why don't we have a "run(function_address)" method so that when constructed with no parameter, we can specify a function to "run" for that thread.
I don't know, why it was designed like this, but I don't see the benefit a run method would have compared to above syntax.
3.1 Or, we can construct a thread with a callable parameter(function, functors, etc.) but call a "run()" method to actually execute the thread later.
You can simulate this by creating a lambda or std::function object and create the thread when you want to run the function.
auto myLambda = [=]{foo(param1, param2);};
// some other code
std::thread myThread(myLambda);
If you want to use the syntax you describe, I'd recommend to write your own Thread wrapper class (should only take a few dozen lines of code) that (optionally) also ensures that the thread is either detached or joined upon destruction of the wrapper, which is - in my opinion - the main problem with std::thread.

C++ Gtk threading. Am I doing it right?

I have a gtkmm application and I'm trying to put some long running tasks into separate threads so they don't lock the GUI. Here's a tutorial I've based my design on:
http://www.velvetcache.org/2008/09/30/gtkmmglibmm-thread-example
I use Glib::Dispatcher signals to notify the GUI thread when the work is done or something needs to be updated, however I'm not sure how to pass the data between the worker thread and GUI thread. So far I've been passing a pointer to the class which creates the worker to the worker and then modifying public members of the class, but something tells me it's not the most correct to do it. Here's an example:
class Some_GUI_class
{
public:
std::string thread_message;
private:
Worker_class* worker;
void start_worker()
{
if (worker != NULL) return;
worker = new Worker_class(this);
worker->sig_message.connect(sigc::mem_fun(*this, &Some_GUI_class::display_message_from_thread);
worker.start();
}
void display_message_from_thread()
{
some_label->set_text(thread_message);
}
}
class Worker_class
{
public:
Worker_class(Some_GUI_class* gui_class) : gui_class(gui_class)
{}
void start()
{
thread = Glib::Thread::create(sigc::mem_fun(*this, &Worker_class::run), true);
}
Glib::Dispather sig_message;
protected:
Glib::Thread* thread;
Glib::Mutex mutex;
Some_GUI_class* gui_class;
void run()
{
// ...
gui_class->thread_message = "Message from a thread!";
sig_message();
}
}
This essentialy works, but I guess if the GUI thread wanted to modify thread_message at the same time there would be a problem? Is it safe to do it like this then as long as I'm sure the variables are only modified by a single thread or is there a better way?
You have a race condition. Even if your gui thread doesn't modify thread_message, allowing the GUI thread to read it while another thread is modifying it is not going to give you long term happiness. This is because std::string is not itself protected from multiple threads accessing it, and has multiple internal fields. If one thread is in the process of modifying one of its internal fields, while another is reading them, the internal state will not be consistent from the point of view of the second.
You can use a mutex in the GUI class to protect access to the variables which might be accessed by another thread. Lock and unlock the mutex in get/set routines, and use those routines for all other accesses to ensure that only one thread gets to access or modify the variables at one time.
Generally mutex usage is not enough to achieve the desired behaviour. The same worker thread (or another one if you have it) could want to send another message while first one had not been processed by the main thread yet. That is why in addition to mutex you should use message queue (e.g. object of std::deque<std::string> class) instead of just a std::string Some_GUI_class::thread_message variable to avoid this kind of message loss.

understanding a qthread subclass's run method and thread context

i have an encoder class with lots of methods . this is a subclass of Qthread. i am new to multi-threading and
trying to understand how this class is
threading its methods
... i understand to thread a method it has to be in a subclass of qthread. and the run of this implements the threaded code for this class. And the thread starts only when a call to start method on the object of this class is made.
Question : firstly what do you infer
from the this run implementation
void Encoder::run(void)
{
VERBOSE(VB_DEBUG, "Encoder::run");
if (WILL_PRINT(VB_DEBUG))
print_stats_timer_id = QObject::startTimer(kEncoderDebugInterval);
health_check_timer_id = QObject::startTimer(kEncoderHealthCheckInterval);
if (init())
exec();
else
VERBOSE(VB_ERROR, "Encoder::run -- failed to initialize encoder");
QObject::killTimer(health_check_timer_id);
if (print_stats_timer_id)
QObject::killTimer(print_stats_timer_id);
cleanup();
}
Question: what does thread context mean in
relation to its methods .
also
Question: what would happen If a method of this
class is called before this class's
thread has started
The class you have written creates a thread and initializes a QObject::timer. It then goes on to call a user defined init() function then the QThread::exec() function.
My guess is that you intended that exec() would be a user defined function where the actual work is to occur. Be aware that QThread::exec() processes the thread's Qt Event Queue.
Also, on some platforms you may get an "Error creating timer from thread" warning message. I've encountered this error on Windows when the code executed fine on Linux
Also, be aware that your timer will never occur if you do not call the QThread::exec() function or QApplication::processEvents() from within your thread.
Thread context in Qt is the same as any other thread concept. That is, all memory is shared between the threaded code (entered at this point in your "run()" function). And any other context which calls into your object. If this object may ever be executing in a thread and accessed from outside of the thread you must protect the shared data.
Because all data is shared between thread contexts (it's a shared memory multiprocessing model) there is no problem with calling functions before/after/during thread execution. Given that:
The object is fully constructed before you call any method. This is not special to threads, necessarily, unless the object is created in a thread.
Any data member is protected with a mutex lock (I eluded to this in #2). QMutexLocker is a handy stack based RAII way of dealing with mutex locks in Qt.
I believe I fully answered your question here, so I'll go ahead and link to RAII and threading articles I have written on another site, just for further reference.
Edit: specificity about threading scenarios:
class MyThreadedClass : public QThread
{
MyThreadClass(const boost::shared_ptr<SomeOtherClass> &t_object)
: m_object(t_object) {}
void doSomething()
{
// Depending on how this method was called (from main, from internal thread)
// will determine which thread this runs on, potentially complicating thread
// safety issues.
m_object->someThing();
}
void run()
{
// I'm now in a thread!
m_object->someFunction(); // oops! The call to someFunction is occurring from
// a thread, this means that SomeOtherClass must be
// threadsafe with mutex guards around shared
// (object level) data.
// do some other stuff
}
};
int main()
{
MyThreadClass thread(someobjectfromsomewhere);
thread.start(); // MyThreadClass is now running
thread.doSomething(); // The call to doSomething occurs from main's thread.
// This means 2 threads are using "thread", main
// and "thread"'s thread.
// The call to thread.doSomething hits Thread.m_object, which means that
// now multiple threads are also accessing m_object ("thread" and "main").
// This can all get very messy very quickly. It's best to tightly control
// how many threads are hitting an object, and how
}
NOTE: It would be a good idea to investigate QFuture, which is designed to handle this kind of asynchronous task, like an encoder, that you are looking at QFuture will avoid some of the potential threading issues of shared data and deadlocks.

Thread-local singletons

I would like to create a singleton class that is instantiated once in each thread where it is used. I would like to store the instance pointers in TLS slots. I have come up with the following solution but I am not sure whether there are any special considerations with multithreaded access to the singelton factory when thread local storage is involved. Maybe there is also a better solution to implement thread local singletons.
class ThreadLocalSingleton
{
static DWORD tlsIndex;
public:
static ThreadLocalSingleton *getInstance()
{
ThreadLocalSingleton *instance =
static_cast<ThreadLocalSingleton*>(TlsGetValue(tlsIndex));
if (!instance) {
instance = new ThreadLocalSingleton();
TlsSetValue(tlsIndex, instance);
}
return instance;
}
};
DWORD ThreadLocalSingleton::tlsIndex = TlsAlloc();
The Tls*-functions are of course win32 specific but portability is not the main issue here. Your thoughts concerning other platforms would still be valuable.
Major Edit: I had originally asked about using double-checked locking in this scenario. However as DavidK pointed out, the singletons are to be created on a per thread basis anyway.
The two remaining questions are:
is it appropriate to reply on TlsGetValue/TlsSetValue to ensure that each thread gets one instance and that the instance is created only once for each thread?
Is it possible to register a callback that allows me to clean up an instance that was associated with a particular thread when that thread finishes?
Since your objects are thread-local, why do you need locking to protect them at all? Each threads that calls getInstance() will be independent of any other thread, so why not just check that the singleton exists and create it if needed? The locking would only be needed if multiple threads tried to access the same singleton, which isn't possible in your design as it is above.
EDIT: Moving on to the two other questions... I can't see any reason why using TlsAlloc/TlsGetValue etc. wouldn't work as you'd expect. Since the memory holding the pointer to your singleton is only accessible to the relevant thread, there won't be any problems with a lazy initialization of it. However there's no explicit callback interface to clean them up.
The obvious solution to that would be to have a method that is called by all your thread main functions that clears up the created singleton, if any.
If it's very likely that the thread will create a singelton, a simpler pattern might be to create the singleton at the start of the thread main function and delete it at the end. You could then use RAII by either creating the singleton on the stack, or holding it in a std::auto_ptr<>, so that it gets deleted when the thread ends. (Unless the thread terminates abnormally, but if that happens all bets are off and a leaked object is the least of your problems.) You could then just pass the singleton around, or store it in TLS, or store it in a member of a class, if most of the thread functionality is in one class.
Have a look at this paper to understand why double-checked locking doesn't work in general (even though it might work in special cases).
We use a class that stores a map of thread id to data to implement our thread local storage. This seems to work very well, then an instance of this class can be placed anywhere you require thread local storage. Normally clients use an instance of as a static private field.
Here is a rough outline of the code
template <class T>
struct ThreadLocal {
T & value()
{
LockGuard<CriticalSection> lock(m_cs);
std::map<int, T>::iterator itr = m_threadMap.find(Thread::getThreadID());
if(itr != m_threadMap.end())
return itr->second;
return m_threadMap.insert(
std::map<int, T>::value_type(BWThread::getThreadID(), T()))
.first->second;
}
CriticalSection m_cs;
std::map<int, T> m_threadMap;
};
This is then used as
class A {
// ...
void doStuff();
private:
static ThreadLocal<Foo> threadLocalFoo;
};
ThreadLocal<Foo> A::threadLocalFoo;
void A::doStuff() {
// ...
threadLocalFoo.value().bar();
// ...
}
This is simple and works on any platform where you can get the thread id. Note the Critical Section is only used to return/create the reference, once you have the reference all calls are outside the critical section.