PDA

View Full Version : Understanding Semaphore Example



KingDavid
12th May 2016, 15:01
Hi,
I don't understand some details about the Semaphores Example (http://doc.qt.io/qt-5/qtcore-threads-semaphores-example.html) QSemaphore.

For simplicity I'll paste the example code:

Global Variables

const int DataSize = 100000;

const int BufferSize = 8192;
char buffer[BufferSize];

QSemaphore freeBytes(BufferSize);
QSemaphore usedBytes;

Producer Class

class Producer : public QThread
{
public:
void run() Q_DECL_OVERRIDE
{
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for (int i = 0; i < DataSize; ++i) {
freeBytes.acquire();
buffer[i % BufferSize] = "ACGT"[(int)qrand() % 4];
usedBytes.release();
}
}
};

Consumer Class


class Consumer : public QThread
{
Q_OBJECT
public:
void run() Q_DECL_OVERRIDE
{
for (int i = 0; i < DataSize; ++i) {
usedBytes.acquire();
fprintf(stderr, "%c", buffer[i % BufferSize]);
freeBytes.release();
}
fprintf(stderr, "\n");
}

signals:
void stringConsumed(const QString &text);

protected:
bool finish;
};

The questions are:

does freeBytes(BufferSize) reserves BufferSize resources or not?
how the consumer is blocked waiting for the usedBytes semaphore to be released?
The example say "Once the producer has put one byte in the buffer, freeBytes.available() is BufferSize - 1 and usedBytes.available() is 1" why the freeBytes is decremented and the usedBytes semaphore is incremented?

anda_skoa
13th May 2016, 08:49
does freeBytes(BufferSize) reserves BufferSize resources or not?

Yes, it does.



how the consumer is blocked waiting for the usedBytes semaphore to be released?

usedBytes is initialized with 0 resources (constructor argument default value), any require() on it will block until enough resources have been made available with respective release() calls.



The example say "Once the producer has put one byte in the buffer, freeBytes.available() is BufferSize - 1 and usedBytes.available() is 1" why the freeBytes is decremented and the usedBytes semaphore is incremented?

freeBytes is decremented because acquire() is being called. Its argument has a default value of 1, so it is decremented by 1.
Similar for usedBytes, its release() is called, again default value being 1, so it increments by 1.

Cheers,
_