patterncppMinor
Producer consumer that simulates the interaction of threads controlling a hardware device
Viewed 0 times
simulatesthethreadsinteractionhardwaredeviceconsumerthatcontrollingproducer
Problem
I have a producer consumer that simulates the interaction of threads controlling a hardware device.
I have 1 thread controlling the device, 1 thread reading, and 1 thread outputting. The read is synchronous on the thread while the controlling is asynchronous.
My producer is the thread controlling the device and my consumer is a thread that processes the data. Often the consumer takes about the same amount of time as the producer (ideal), but sometimes it takes more time.
The hope is that the producer should not produce more than the consumer can process. This is partly due to hardware overflow, the consumer will free a buffer on the device, and partly due to visual latency.
I think the producer should be responsible for regulating the rate of production. I implemented this regulation using a sleep timeout.
I am wondering if this is the best way to do it.
My heuristic for success is the time output of the redraw command, which should be roughly
```
#include
#include
#include
#include
#include
#include
//UTILITY
//
using namespace std;
#if !defined(WIN32)
#include
void
_sleep (int ms)
{
usleep (ms * 1000); //convert to microseconds
}
#endif
long long
timestamp ()
{
auto now = std::chrono::system_clock::now ();
auto duration = now.time_since_epoch ();
auto millis = std::chrono::duration_cast(duration).count ();
return millis;
}
//REDRAW
//
bool killRedraw;
bool drawIt;
long long last;
void
redraw ()
{
cout balance;
bool killProducer;
void
produce ()
{
cout 1)
{
_sleep (10);
}
}
}
//CONSUMER
//
bool killConsumer;
void
consume ()
{
cout << "Ate one:" << --balance << endl;
}
void
consumer ()
{
cout << "Starting consumer thread" << endl;
while (!killConsumer)
{
int basetime = 35;
int noise = rand () % 20;
_sleep (basetime + noise);
consume ();
static int cycle = -1;
if ((cycle = ++cycle % 8) == 7)
I have 1 thread controlling the device, 1 thread reading, and 1 thread outputting. The read is synchronous on the thread while the controlling is asynchronous.
My producer is the thread controlling the device and my consumer is a thread that processes the data. Often the consumer takes about the same amount of time as the producer (ideal), but sometimes it takes more time.
The hope is that the producer should not produce more than the consumer can process. This is partly due to hardware overflow, the consumer will free a buffer on the device, and partly due to visual latency.
I think the producer should be responsible for regulating the rate of production. I implemented this regulation using a sleep timeout.
I am wondering if this is the best way to do it.
My heuristic for success is the time output of the redraw command, which should be roughly
ConsumerTime*8 (maybe 400).```
#include
#include
#include
#include
#include
#include
//UTILITY
//
using namespace std;
#if !defined(WIN32)
#include
void
_sleep (int ms)
{
usleep (ms * 1000); //convert to microseconds
}
#endif
long long
timestamp ()
{
auto now = std::chrono::system_clock::now ();
auto duration = now.time_since_epoch ();
auto millis = std::chrono::duration_cast(duration).count ();
return millis;
}
//REDRAW
//
bool killRedraw;
bool drawIt;
long long last;
void
redraw ()
{
cout balance;
bool killProducer;
void
produce ()
{
cout 1)
{
_sleep (10);
}
}
}
//CONSUMER
//
bool killConsumer;
void
consume ()
{
cout << "Ate one:" << --balance << endl;
}
void
consumer ()
{
cout << "Starting consumer thread" << endl;
while (!killConsumer)
{
int basetime = 35;
int noise = rand () % 20;
_sleep (basetime + noise);
consume ();
static int cycle = -1;
if ((cycle = ++cycle % 8) == 7)
Solution
I have some minor things to point out:
-
There is not a single empty line in this code, and this essentially looks like globals, functions, and comments stacked on top of each other. You should have each type separated so that the code is easier to read (especially with the function names and return types on separate lines).
-
Since you're using C++11, you should be using `
-
There is not a single empty line in this code, and this essentially looks like globals, functions, and comments stacked on top of each other. You should have each type separated so that the code is easier to read (especially with the function names and return types on separate lines).
-
Since you're using C++11, you should be using `
in place of std::rand. It has been determined that rand() is harmful and should no longer be used in C++11.
-
Unless I'm misunderstanding the use of multithreading here, I don't think you should be using any global variables, as they're prone to bugs. If that's the case, then you should just be passing them to functions as needed. If not, then at least put them all towards the top (they're already global, so it doesn't make a difference to have them in different places outside the functions).
-
You don't need to be using std::endl everywhere. It doesn't appear that you're needing to flush the buffer each time, which can also affect performance. Instead, output a "\n"` to produce a newline without also flushing the buffer.Context
StackExchange Code Review Q#26357, answer score: 4
Revisions (0)
No revisions yet.