rkreddy_kbs
asked on
QWaitCondition
Hello
I want to implement 2 threads (Producer/Consumer) in Qt 4.6.2 that interact with each other using QWaitCondition (i.e., wait/notify meaning T1 does something, notifies T2 and goes to wait again . The thread T2 who until now was waiting, when notified by T1, wakes up, does something and then notifies T1 and so on..)
Is QWaitCondition the right choice or is there something else.. I implemented the code but it gets into some deadlock. Here is my code :-
I want to implement 2 threads (Producer/Consumer) in Qt 4.6.2 that interact with each other using QWaitCondition (i.e., wait/notify meaning T1 does something, notifies T2 and goes to wait again . The thread T2 who until now was waiting, when notified by T1, wakes up, does something and then notifies T1 and so on..)
Is QWaitCondition the right choice or is there something else.. I implemented the code but it gets into some deadlock. Here is my code :-
class DemoApp : public QMainWindow {
Q_OBJECT
public:
DemoApp(QWidget *parent = 0);
~DemoApp();
QMutex wmutex, rmutex;
QWaitCondition permitToWrite;
QWaitCondition permitToRead;
private:
WriterThread *wthread; // this is our writer thread
ReaderThread *rthread; // this is our reader thread
}
void DemoApp::on_StartButton_clicked()
{
wthread = new WriterThread(this);
wthread->start();
rthread = new ReaderThread(this);
rthread->start();
permitToWrite.wakeAll();
}
//Writer Thread
WriterThread::WriterThread(QObject *parent)
: QThread(parent)
{
myParent = (DemoApp*)parent;
}
void WriterThread::run()
{
while(1){
{
myParent->wmutex.lock();
myParent->permitToWrite.wait(&myParent->wmutex);
writeSomething();
myParent->wmutex.unlock();
myParent->permitToRead.wakeAll();
}
}
//Reader Thread
ReaderThread::ReaderThread(QObject *parent)
: QThread(parent)
{
myParent = (DemoApp*)parent;
}
void ReaderThread::run()
{
while(1){
{
myParent->rmutex.lock();
myParent->permitToRead.wait(&myParent->rmutex);
readSomething();
myParent->rmutex.unlock();
myParent->permitToWrite.wakeAll();
}
}
ASKER
I made the following changes and it seems to be working :-
Firstly use only mutex instead of wmutex and rmutex
Firstly use only mutex instead of wmutex and rmutex
void WriterThread::run()
{
while(1){
{
myParent->mutex.tryLock();
myParent->permitToWrite.wait(&myParent->mutex);
writeSomething();
myParent->permitToRead.wakeAll();
}
}
void ReaderThread::run()
{
while(1){
{
myParent->mutex.tryLock();
myParent->permitToRead.wait(&myParent->mutex);
readSomething();
myParent->permitToWrite.wakeAll();
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
For most of the iterations, they work correctly as follows :-
The W (writer) writesSomething, unlocks wmutex, wakes Reader, locks wmutex and then waits on permitToWrite.
The reader R is scheduled and it does its sequence as readSomething, unlock rmutex, wakes Writer, lock rmutex and then waits on permitToRead
the above steps repeat but after some time, the sequence gets disturbed as follows :-
The W (writer) writesSomething, unlocks wmutex, wakes Reader.
Now the reader is scheduled
The reader does its sequence as readSomething, unlock rmutex, wakes Writer, lock rmutex and then waits on permitToRead. Note here that the writer has been woken up but it was never waiting.
Now the writer is scheduled and it continues from where it left i.e. unlock wmutex and then waits on permitToWrite and it waits indefinitely here.
So now both reader and writer are waiting indefinitely for their respective permits.
Should I be using the same mutex instead of two mutexes. I tried but it did not work either.. pls advise.