Sharing data generated by one thread with an array of other threads
Having a thread that from time to time (thread with one function in infinite loop, data is generat开发者_Go百科ed when function finishes) generated some data (for example random int). And heaving 3 other threads that need to get that generated data from time to time (threads with one function in infinite loop, data is required when function starts). All that 3 threads want to modify that int during there circle and return something different.
How do I make data generated by first thread accessible by other threads? (sorry - I am C++ nob. I can use boost library. I beg you please provide code with your answers.)
Here is a primitive example, that demonstrate how to create a thread that produces random numbers and puts them in a queue, and three consumer thread which extract random numbers from the queue and print them if the random numbers are odd only. This example can be vastly improved, and many best practices are not followed for the sake of explaining the basic facilities(thread_group, mutex and random number generation all using boost):
#include <iostream>
#include <queue>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/random.hpp>
#include <boost/bind.hpp>
std::queue<int> random_stream;
boost::mutex random_stream_mutex, output_mutex;
// create a random number generator similar to good ol' std::rand!
boost::mt19937 rand_generator;
boost::uniform_int<> distribution;
auto random_producer = boost::bind(distribution, rand_generator);
bool isodd(int number)
{ return number % 2 == 1; }
void random_generator()
{
for(;;)
{
// generate a random number, then lock the queue and push
// the number into it.
int random_number = random_producer();
random_stream_mutex.lock();
random_stream.push(random_number);
random_stream_mutex.unlock();
}
}
void output_odd_randoms()
{
for(;;)
{
// lock the queue then extract the number.
random_stream_mutex.lock();
int random_number = random_stream.front();
random_stream.pop();
random_stream_mutex.unlock();
// print the extracted number if it is odd!
if(isodd(random_number))
{
output_mutex.lock();
std::cout << boost::this_thread::get_id() << ": "
<< random_number << std::endl;
output_mutex.unlock();
}
}
}
int main()
{
// create the producer and the consumers!
boost::thread_group threads;
threads.create_thread(random_generator);
threads.create_thread(output_odd_randoms);
threads.create_thread(output_odd_randoms);
threads.create_thread(output_odd_randoms);
// wait for ever! :)
threads.join_all();
}
As you can see, the code uses global variables but encapsulating your data is a better idea. Also, using RAII locking mechanism is more elegant but modifying the code to add them is trivial.
Hope that helps,
There are many ways to do this, depending on the details. Since you do not provide many details, let's go with something simple and bulletproof.
- Create a class
- Add a private data member to store the data
- Add thread safe get and put methods to read and write the data
- Construct your class in the global namespace
- Code your threads to use the get and put methods as required
How do you make thread safe get and put methods?
- Add a private mutex to your class.
- Lock the mutex on entry to the get and put methods
- Unlock the mutex on exit from the get and put methods.
Something like this:
class mySafeData
{
public:
void Set( int i )
{
myMutex.lock();
myData = i;
myMutex.unlock();
}
void Get( int& i)
{
myMutex.lock();
i = myData;
myMutex.unlock();
}
private:
int myData;
boost::mutex myMutex;
};
This method is not efficient. IMHO it is important to get code working using the simplest and most easily understood technique. Once it is working then, if performance is a problem, the code can be optimized.
精彩评论