Preamble
A very simple example of a single producer/consumer using locks and move operations.
Code
[js]
template
class ProdCon
{
public:
void push(T&& w_)
{
scoped_lock
if (_q.empty())
{
_cv.notify_one();
}
_q.emplace(move(w_));
}
T pop()
{
unique_lock
_cv.wait(lock, [this](){ return !_q.empty(); } );
auto& w = _q.front();
_q.pop();
return move(w);
}
private:
queue
mutex _mtx;
condition_variable _cv;
};
[/js]
Points to note are:
Full code
[js]
#include
#include
#include
#include
using namespace std;
template
class ProdCon
{
public:
void push(T&& w_)
{
scoped_lock
if (_q.empty())
{
_cv.notify_one();
}
_q.emplace(move(w_));
}
T pop()
{
unique_lock
_cv.wait(lock, [this](){ return !_q.empty(); } );
auto& w = _q.front();
_q.pop();
return move(w);
}
private:
queue
mutex _mtx;
condition_variable _cv;
};
//——————-TestCode———————–
static int widgetNum = 1;
class Widget
{
public:
Widget() : _widgetNum{widgetNum++} {}
Widget(const Widget&) = delete;
Widget& operator=(const Widget&) = delete;
Widget(Widget&&) = default;
Widget& operator=(Widget&&) = default;
int num() { return _widgetNum; }
private:
int _widgetNum;
};
void staticTest()
{
cout << "staticTest" << endl;
widgetNum = 1;
Widget w1, w2, w3, w4;
ProdCon
pc.push(move(w1));
pc.push(move(w2));
cout << pc.pop().num() << endl;
cout << pc.pop().num() << endl;
pc.push(move(w3));
cout << pc.pop().num() << endl;
pc.push(move(w4));
cout << pc.pop().num() << endl;
}
void dynamicTest()
{
cout << "dynamicTest" << endl;
widgetNum = 1;
Widget w1, w2, w3, w4;
ProdCon
auto prod = [&](){ pc.push(move(w1)); pc.push(move(w2)); pc.push(move(w3)); pc.push(move(w4)); };
auto con = [&](){ for(int i = 1; i<=4; ++i) {cout << pc.pop().num() << endl;}; };
auto fut = async(launch::async, con);
async(launch::async, prod);
//wait for consumer
fut.get();
}
int main()
{
staticTest();
dynamicTest();
return 0;
}
[/js]