Re: Passing generic data between thread
ittium <ittium@gmail.com> wrote in news:4ffcecec-f711-4d18-ae6d-
35a7ad540c8f@r33g2000prh.googlegroups.com:
I want to pass data between two threads. Type of data can vary.
data
{
list l;
map m;
}
data
{
int i;
long l;
}
There is no inherent reason why thread passing should cause any loss of
loss of type-safety and require resorting to void* pointers. I suspect
rather that you want to pass the data through some queue or some other
restricted interface, and the question should rather be: how to pass
different types of data through a queue? The rest of my response is
rather assuming the latter question.
I can think of following ways to do it
1. write serialise routines so that between the thread, encoded void*
buffer is passed. But since thread will run in same address space,
serialization seems to me as overkill.
Yes, this would be a serious overkill and going against the idea of
multithreading in general.
2. Pass a token (specifying the type) and data typecasted to void*.
Receiving thread can typecast the data to actual type based on the
token
The data is most probably allocated dynamically, so it needs to be
deleted eventually. While it is living in the queue as a void*, it cannot
be deleted properly; this may or may not be a problem.
3. Use boost:any and then receiver can find out type using RTTI.
Either this or some other kind of variant type, which will be able to
clean up the data properly is the item is lost or discarded "between the
threads".
Since large amount of data is to be processed, CPU utilization is
important concern.
Using raw pointers like void* is efficient, but fragile. Especially the
exception safety is hard to get right. On the other hand, using value
types may cause lots of unneeded copying of data if you are not careful.
The upcoming C++0x standard provides special move constructors for this
kind of operations, meanwhile one can resort to the swap idiom. For
example, a push operation into a queue of (large) strings could look
like:
std::deque<std::string> q;
// ...
std::string data = ...;
scoped_lock lock(q_mutex);
q.push_back(std::string());
q.back().swap(data);
The pop operation (in the other thread) would similarly swap the string
out of the queue.
See, no (explicit) dynamic allocation, nothing to free, no type-safety
loss, no danger to stomp on the string from two threads at the same time,
and still the thing is quite efficient.
I will appreciate your experiences of solving similar problem.
Inter-thread queues like sketched above have worked well for me. For
passing variable data I use my own variant class containing a type flag
and a union (and having an efficient swap method of course).
hth
Paavo