0

I am currently testing out pthreads for usage in order to speed up other code I have. Essentially what my code currently has is a couple of for loops that end up doing matrix calculations. I tried spawning threads that will do those calculations simultaneously, and it ended up cutting the runtime in half.

My question is that, is there a way to initially spawn these pthreads, have them run the function, and use them again later to run the same function without them closing? Or is it necessary to close them after performing the task?

I am using Windows by the way, using a pthreads library.

G Boggs
  • 381
  • 1
  • 6
  • 19
  • 2
    Pass a pointer to a queue to the thread. Have the thread check if the queue is empty. If it isn't, run the next function in the queue. If it is empty, yield/sleep in a loop maybe. You could probably just "notify" the thread when there is a new function in the queue. The queue will have to outlive the life of the thread. Maybe "static" or "atomic" queue would work. You might need synchronisation if more than one thread can access the queue. – Brandon Aug 26 '14 at 16:00
  • 2
    Just to save you a lot of pain in the long run, The C++ standard library contains a far nicer (and safer) threading library than pthreads, and it doesn't require you to link to third-party libraries – jalf Aug 26 '14 at 16:09

2 Answers2

2

You could create a queue of tasks, that your threads will sample for new tasks and dequeue if any are present (and preferably some cancellation flag to gracefully stop them).

You'd need to make the addition of tasks thread-safe by e.g using a pthread_mutex.

You could also use a conditional variable (pthread_cond_t) to signal when are there more tasks to cunsume

This way you could spawn as many threads as you wish in the beginning, and just add tasks when needed.


As a side note you should probably prefer the less cumbersome threading of the standard library.

Scis
  • 2,934
  • 3
  • 23
  • 37
  • I'm sorry, I'm a little new to multithreading in general, could you elaborate on this please? – G Boggs Aug 26 '14 at 15:59
  • @GBoggs You could use [this](https://computing.llnl.gov/tutorials/pthreads/) tutorial which is OK and has some examples (like a threaded dot product which uses mutexes) – Scis Aug 26 '14 at 16:08
  • a single shared work queue becomes a bottleneck for distributing a significant number of not too big tasks across several or more threads. On the other hand, if the tasks are big enough to hide overheads and contention on the queue, it can lead to sub-optimal load balancing and underutilized processing resources. See my answer for a better solution. – Anton Aug 26 '14 at 18:00
  • @Anton I'm well aware of the existence of those libraries, but considering the OP specifically asked whether "... a pthread (Windows) be kept open to run a function multiple times?" and not "What's the best parallel-processing library?" I think that your answer while utilizes clearly superior technologies does not address the OP's original question. Plus the OP states that he's "a little new to multithreading in general" so it might be a good idea to get to know basic threading concepts. – Scis Aug 26 '14 at 18:35
  • Agree on the basics. But given the 'a little new' and 'for loops' to be run in parallel, I doubt that OP really wants working with threads directly - it's like using assembler for text processing. – Anton Aug 26 '14 at 18:47
0

Why not to use full-fledged parallel-processing libraries or language extensions like , , . All these are quite portable now, having support from main OSes and compilers. Microsoft also has which is TBB's twin.

So, you don't have to invent the wheel but let the libraries to take care of threads and the load balance; and prevent you from traps like this: Why is OpenMP outperforming threads?

For example, the vector of tasks can be run in parallel by default number of threads as simple as (in cilk):

cilk_for(int i = 0; i < tasks.size(); i++)
    task[i].some_function();

You can also change the number of threads if needed.

Community
  • 1
  • 1
Anton
  • 6,349
  • 1
  • 25
  • 53