tags:

views:

130

answers:

4

I am creating a data-parallel program using pthreads and C++. From http://stackoverflow.com/questions/1151582/pthread-function-from-a-class, I found out how to supply pthread_create with a function pointer to a static C++ function(and supply it a this argument).

However, I also need to supply the thread with an index, so it knows what data it's working on. I could malloc a struct for each thread(with both the pointer to the C++ class and an index), but this seems like it would add some bookkeeping code, and could lead to leaks if the struct isn't freed. Is there a better way to do this?

+8  A: 

You can use Boost.Thread. It provides a type-safe way for you to pass more than one argument into your callable.

Yes, it has similar kinds of bookkeeping as your question stated, but it uses C++ mechanisms to ensure that it doesn't leak.

Chris Jester-Young
Any thread library would be a good recomendation, but boost::thread is the closest I know to the next standard threads, so this is probably the best recomendation for someone that programs C++
David Rodríguez - dribeas
+4  A: 

Is there a better way to do this?

Not really. Since thread functions can only take a single void * argument, any and all data that you want to pass to the thread function has to be part of a struct or class that contains the data you need. The usual design pattern is to have a ThreadParameters class or struct that contains everything that you need, and which you can add to if you need to have more parameters.

The most straightforward way to handle freeing is to have the person that creates the thread allocate the ThreadParameters, and have the thread itself free the ThreadParameters just before it exits.

JSBangs
+4  A: 

Unless you are passing the same C++ object as the this pointer to multiple concurrent threads, you should simply add the index to the object.

I would recommend having one object per thread, to make debugging easier if nothing else. Make your current this class a resource shared by reference between thread objects.

If that means adding new objects on the heap, simply delete them immediately after calling pthread_join. Not much room for error, really.

Potatoswatter
The issue with putting the index in the object is that many objects are accessing the class, and I need a way to differentiate them.
Mike
@Mike: "many objects are accessing the class" doesn't make sense. Objects belong to classes and access other objects. It would probably improve the organization of your program to have an object to represent each thread, even if it only consists of an index and a pointer (and a `pthread_t` — where do you have your thread objects now?). The other good suggestion, to learn and use a thread library, is equivalent: any thread library will be centered on objects representing threads!
Potatoswatter
+1  A: 

If there is an object (class instance) associated with each thread. (I inferred this from your reference to this.) You could just make the index a member of the class. This could be configured in the constructor or using alternatively using a setter.

class C { 
  Index index_; 
public:
  C(Index &index) : index_(idx) {}
  void Run() { ... }
}

Index workSet;
C worker(workSet);
worker.Run();
Marc