Edit: Here's my test case (see Coliru) that produces dummy objects and outputs which of those could be consumed. For some reason, there will be major gaps, i.e. large numbers of subsequent objects are not consumed. I guess that happens whenever std::cout
's buffer is flushed.
#include "spsc_object.hpp"
#include <cassert>
#include <atomic>
#include <future>
#include <iostream>
struct test_t {
int x, y;
test_t(int x) : x(x), y(1) {}
~test_t() {
y = 0;
}
};
const int to_produce = 10000000;
spsc_object<test_t> object;
std::atomic_bool stop_consuming;
int producer()
{
int written = 0;
for (int i = 0; i < to_produce; i++) {
if (object.write(test_t(i)))
written++;
}
return written;
}
int consumer()
{
int read = 0;
for (;;) {
test_t mytest(3);
if (object.read([&mytest](const test_t& test) {
mytest = test;
})) {
read++;
// Here go expensive calculations
std::cout << mytest.x << '\n';
assert(mytest.y != 0);
} else if (stop_consuming) {
return read;
} else {
// Should not happen unless only a single hardware thread is
// available for both producer and consumer, as seems to be the case
// on Coliru for example.
std::cout << "Oh boy, the producer was too slow!\n";
}
}
}
int main()
{
stop_consuming = false;
auto t1 = std::async(std::launch::async, producer);
auto t2 = std::async(std::launch::async, consumer);
int written = t1.get();
stop_consuming = true;
int read = t2.get();
std::cout << "produced = " << to_produce << "\n"
"written = " << written << "\n"
"read = consumed = " << read << '\n';
}
Sample output:
...
9908795
9908803
9908812
9908822
9908832
9908842
9908852
9908861
9908872
9908881
9908891
9908898
9908907
9908917
9908928
9908938
9908948
produced = 10000000
written = 37374
read = consumed = 37374