PDA

View Full Version : QSemaphore::acquire() and QObject::timerEvent ( QTimerEvent * event )



babu198649
15th July 2008, 15:01
hi
Does using QSemaphore::acquire()inside QThread's timerEvent ( QTimerEvent * event ) will freeze the application.

wysota
15th July 2008, 15:29
Not by itself. If you experience a freeze, it is possible you have a deadlock in your program.

babu198649
17th July 2008, 08:34
In the below program the Thread_write class writes data to a buffer every 100 milliseconds and the Thread_read reads the data from the buffer after the data has been written(this process will continue only 10 times).But even the timer is not started but the run function is executed ,where am i wrong.


#include <QtGui>

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

QSemaphore freeB(BufferSize);
QSemaphore usedB;

class Thread_write : public QThread
{
public:
void run()
{
startTimer(100);
}

void timerEvent(QTimerEvent *)
{
for (int i=0; i<BufferSize; i++)
{
freeB.acquire();
buffer[i]=i;
usedB.release();
}
}
};

class Thread_read : public QThread
{
public:
void run()
{
for (int i=0; i<BufferSize; i++)
{
usedB.acquire();
qDebug()<<buffer[i];
freeB.release();
}
}
};

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Thread_write tw;
tw.start();

Thread_read tr;
tr.start();
return a.exec();
}

wysota
17th July 2008, 12:10
For timers to fire you need an event loop running in your thread. Your thread doesn't spin one - call QThread::exec(). Currently your writer thread does nothing and exits immediately.

babu198649
19th July 2008, 08:16
Even after calling exec() in run() function ,the result is the same.

wysota
20th July 2008, 15:02
Currently your design doesn't make much sense - the timerEvent will be fired only once and will then perform a loop preventing other events to be processed. You could as well move the loop to the run() method so both thread classes would be equivalent. What exactly are you trying to obtain?

babu198649
21st July 2008, 10:19
In the first thread ,i want to collect data from external source every 1000 milliseconds and store it in circular buffer.

In the second thread, the data is fetched from the circular buffer and computation of the data is done which is time consuming.

wysota
26th July 2008, 13:24
In that case your producer thread is incorrect. You would be trying to write the data to the whole buffer every 100ms starting from the beginning each time. Store the current "first empty" and "first full" indexes to the buffer and write one item at a time. If you are using semaphores to synchronize threads, you don't need a timer, it won't work properly anyway. Simply run the producer function all the time you have new data to process. You might even use tryAcquire() so that you can return the flow elsewhere if the buffer is full.