views:

4240

answers:

3

Wish to simultaneously call a function multiple times. I wish to use threads to call a function which will utilize the machines capability to the fullest. This is a 8 core machine, and my requirement is to use the machine cpu from 10% to 100% or more.

My requirement is to use the boost class. Is there any way I can accomplish this using the boost thread or threadpool library? Or some other way to do it?

Also, if I have to call multiple functions with different parameters each time (with separate threads), what is the best way to do this? [using boost or not using boost] and how?

#include <iostream>
#include <fstream>
#include <string.h>
#include <time.h>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>

using namespace std;
using boost::mutex;
using boost::thread;

int threadedAPI1( );
int threadedAPI2( );
int threadedAPI3( );
int threadedAPI4( );

int threadedAPI1( ) {
 cout << "Thread0" << endl;
}


int threadedAPI2( ) {
 cout << "Thread1" << endl;
}

int threadedAPI3( ) {
 cout << "Thread2" << endl;
}

int threadedAPI4( ) {
 cout << "Thread3" << endl;
}

int main(int argc, char* argv[]) {

 boost::threadpool::thread_pool<> threads(4);
 // start a new thread that calls the "threadLockedAPI" function
 threads.schedule(boost::bind(&threadedAPI1,0));
 threads.schedule(boost::bind(&threadedAPI2,1));
 threads.schedule(boost::bind(&threadedAPI3,2));
 threads.schedule(boost::bind(&threadedAPI4,3));
 // wait for the thread to finish
 threads.wait();

 return 0;
}

The above is not working and I am not sure why? :-(

+3  A: 

If your interest is in using your processor effeciently then you might want to consider intels thread building blocks http://www.intel.com/cd/software/products/asmo-na/eng/294797.htm. I believe it is designed specifically to utilise multi core processors while boost threads leaves control up to the user (i.e. TBB will thread differently on a quad core compared to a dual core).

As for your code you are binding functions which don't take parameters to a parameter. Why? You might also want to check the return code from schedule.

Patrick
thanks patrick. actually have modified the question to be more specific. i wanted to find something which will let me call multiple functions simultaneously. also, am not sure as to how to send parameters.
gagneet
+4  A: 

You're binding parameters to functions that don't take parameters:

int threadedAPI1( );

boost::bind(&threadedAPI1,0)

Just pass the function directly if there are no parameters:

threads.schedule(&threadedAPI1)
James Hopkin
what is the correct way to do it then?
gagneet
+3  A: 

I suggest that you read up on the documentation for the functions you use. From your comment in James Hopkin's answer, it seems like you don't know what boost::bind does, but simply copy-pasted the code.

boost::bind takes a function (call it f), and optionally a number of parameters, and returns a function which, when called, calls f with the specified parameters.

That is, boost::bind(threadedAPI1, 0)() (creating a function which takes no arguments and calls threadedAPI1() with the argument 0, and then calling that) is equivalent to threadedAPI1(0).

Since your threadedAPI functions don't actually take any parameters, you can't pass any arguments to them. That is just fundamental C++. You can't call threadedAPI1(0), but only threadedAPI1(), and yet when you call the function, you try (via boost::bind) to pass the integer 0 as an argument.

So the simple answer to your question is to simply define threadedAPI1 as follows:

int threadedAPI1(int i);

However, one way to avoid the boost::bind calls is to call a functor instead of a free function when launching the thread. Declare a class something like this:

struct threadedAPI {
  threadedAPI(int i) : i(i) {} // A constructor taking the arguments you wish to pass to the thread, and saves them in the class instance.

  void operator()() { // The () operator is the function that is actually called when the thread starts, and because it is just a regular class member function, it can see the 'i' variable initialized by the constructor
    cout << "Thread" << i << endl; // No need to create 4 identical functions. We can just reuse this one, and pass a different `i` each time we call it.
  }
private:
  int i;
};

Finally, depending on what you need, plain threads may be better suited than a threadpool. In general, a thread pool only runs a limited number of threads, so it may queue up some tasks until one of its threads finish executing. It is mainly intended for cases where you have many short-lived tasks.

If you have a fixed number of longer-duration tasks, creating a dedicated thread for each may be the way to go.

jalf
thanks, this seems to make a lot of sense. sorry for not reading up on the docs before posting.
gagneet