I've made a small skeleton for a larger project that will include cross-platform multithreading (by using Boost) and thread-safe random numbers (by using GNU scientific libraries and mutexes). My goal is to run a simulation (probably over 100,000 loops) in which each thread will utilize a random number and read from a library that the threads will not change the value of (thus, I don't bother putting the library in a mutex)!
Is this code alright?
#include <stdio.h> // Standard in out for c
#include <vector> // Vectors
#include <boost/thread.hpp> // Boost threads
#include <boost/signals2/mutex.hpp> // Boost mutexes
#include <gsl/gsl_rng.h> // Gnu Scientific Library, thread safe rand
const gsl_rng_type * T = gsl_rng_default; // Select random generator
gsl_rng * r = gsl_rng_alloc (T); // Allocate the range
boost::mutex mtx; // Create a mutex
std::vector<unsigned long> data; // Create a vector
int count=23; // Have a total number of threadFunctions you want to loop through
int CORES = static_cast<int>(boost::thread::hardware_concurrency());
void threadFunction(int id);
int main()
{
printf("Number of cores = %d\n-------------------\n\n",CORES);
gsl_rng_env_setup(); // Setup the random variable environment
gsl_rng_set (r,time(NULL)); // Seed the r generator
std::vector<boost::thread *> t; // Create vector of boost::thread pointers
while(count>0){ // While you are looping
for(int i=0;i<((CORES>count?count:CORES));i++) // Create 4 threads if more than 4 loops are left, else create the appropriate number of threads
t.push_back(new boost::thread(threadFunction,i)); // Push threads objects back
for(int i=0;i<t.size();i++){ // Loop through all threads
t[i]->join(); // Wait to join. Note, these are pointers so use -> instead of .
count--; // Reduce count by 1
}
t.resize(0); // Empty the array
}
printf("\nEnd of threads...");
FILE *out = fopen("RandomNumbers.txt","w+"); // Create a file to hold values
for(int i=0;i<data.size();i++) // Print out values
fprintf(out,"%lu\n",data[i]);
fclose(out); // Close file
printf("\nPress Enter to exit...");
getchar();
return 0;
}
void threadFunction(int id)
{
{ // By scoping in, the lock_guard can destroy itself upon exit
boost::lock_guard<boost::mutex> ownlock(mtx); // Create lock_guard
data.push_back(gsl_rng_get(r)); // Put a random number in data
}
printf("Working on %d...\n",id);
}
boost::thread_group
to create threads (instead ofvector<boost::thread>
). \$\endgroup\$