?
=?iso-8859-1?B?Tm9yZGz2dw==?=
Hey there, C++ Coders!
I am learning multi-threading with boost and have come up with the
following code example shown below.
This example implements a test of the producer-consumer design
pattern.
gcc-4.1.2 however complains with errors about my use of boost::bind().
Doesn't bind support this way of specifying a function and its
arguments or should I solve it in another way?
Many thanks in advance,
Per Nordlöw
=========== test_threadsafety.cpp begins =============
#include "threadsafe_queue.hpp"
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
void produce(threadsafe_queue<T> & q, uint n)
{
for (uint i = 0; i < n; i++) {
T x = i;
q.push(x);
cout << "i:" << i << " produced: " << x << endl;
}
}
template <typename T>
void consume(threadsafe_queue<T> & q, uint n)
{
for (uint i = 0; i < n; i++) {
T x = q.wait_pop();
cout << "i:" << i << " consumed: " << x << endl;
}
}
int main()
{
threadsafe_queue<float> q;
boost::thread pt(boost::bind(produce<float>, q, 10));
boost::thread ct(boost::bind(consume<float>, q, 10));
pt.join();
ct.join();
return 0;
}
=========== test_threadsafety.cpp ends =============
=========== threadsafe_queue.hpp begins =============
#ifndef PNW__THREADSAFE_QUEUE_HPP
#define PNW__THREADSAFE_QUEUE_HPP
/***
* @file threadsafe_queue.hpp
* @brief Thread Safe wrapper on std:queue using Boost.
*/
#include <queue>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
template <typename T>
class threadsafe_queue
{
std::queue<T> q; ///< Queue.
boost::mutex m; ///< Mutex.
boost::condition c; ///< Condition.
public:
/***
* Push @p value.
*/
void push(const T & value) {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
q.push(value);
}
/***
* Try and pop into @p value, returning directly in any case.
* @return true if pop was success, false otherwise.
*/
bool try_pop(T & value) {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
if (q.size()) {
value = q.front();
q.pop();
return true;
}
return false;
}
/// Pop into @p value, while possibly waiting forever.
T wait_pop() {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
// wait until queue has at least on element()
c.wait(sl, boost::bind(&std::queue<T>::size, q));
T value = q.front();
q.pop();
return value;
}
};
#endif
=========== threadsafe_queue.hpp ends =============
I am learning multi-threading with boost and have come up with the
following code example shown below.
This example implements a test of the producer-consumer design
pattern.
gcc-4.1.2 however complains with errors about my use of boost::bind().
Doesn't bind support this way of specifying a function and its
arguments or should I solve it in another way?
Many thanks in advance,
Per Nordlöw
=========== test_threadsafety.cpp begins =============
#include "threadsafe_queue.hpp"
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
void produce(threadsafe_queue<T> & q, uint n)
{
for (uint i = 0; i < n; i++) {
T x = i;
q.push(x);
cout << "i:" << i << " produced: " << x << endl;
}
}
template <typename T>
void consume(threadsafe_queue<T> & q, uint n)
{
for (uint i = 0; i < n; i++) {
T x = q.wait_pop();
cout << "i:" << i << " consumed: " << x << endl;
}
}
int main()
{
threadsafe_queue<float> q;
boost::thread pt(boost::bind(produce<float>, q, 10));
boost::thread ct(boost::bind(consume<float>, q, 10));
pt.join();
ct.join();
return 0;
}
=========== test_threadsafety.cpp ends =============
=========== threadsafe_queue.hpp begins =============
#ifndef PNW__THREADSAFE_QUEUE_HPP
#define PNW__THREADSAFE_QUEUE_HPP
/***
* @file threadsafe_queue.hpp
* @brief Thread Safe wrapper on std:queue using Boost.
*/
#include <queue>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
template <typename T>
class threadsafe_queue
{
std::queue<T> q; ///< Queue.
boost::mutex m; ///< Mutex.
boost::condition c; ///< Condition.
public:
/***
* Push @p value.
*/
void push(const T & value) {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
q.push(value);
}
/***
* Try and pop into @p value, returning directly in any case.
* @return true if pop was success, false otherwise.
*/
bool try_pop(T & value) {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
if (q.size()) {
value = q.front();
q.pop();
return true;
}
return false;
}
/// Pop into @p value, while possibly waiting forever.
T wait_pop() {
boost::mutex::scoped_lock sl(m); // NOTE: lock mutex
// wait until queue has at least on element()
c.wait(sl, boost::bind(&std::queue<T>::size, q));
T value = q.front();
q.pop();
return value;
}
};
#endif
=========== threadsafe_queue.hpp ends =============