Calling QSerialPort methods from two different threads
Hi.
I am trying to write a class that makes sync and async requests to some device on a serial port, but it always shows me worrisome
messages like:
Quote:
QObject::killTimer: Timers cannot be stopped from another thread
QObject::startTimer: Timers cannot be started from another thread
For the sake of presentation I wrote a simple class (below). I know I can do it other ways but this way its much easier to implement communication timeouts, request repetition, received packet completion etc. It's also easy to implement sync methods, as I can just call directly internal blocking methods of object owned by worker thread (QSerialPort in this example).
There is no event loop in worker thread, threads are synchronized, so it should be perfectly safe to call syncWrite method from main thread, but then I get those messages. Is there any easy way out to solve this problem?
Thank you.
Code:
class SerialThread
: public QThread{
Q_OBJECT
public:
SerialThread()
{
}
~SerialThread()
{
quit.lock();
wait();
}
{
buffer = data;
}
{
serial->write(data);
if(serial->waitForReadyRead(1000))
{
data = serial->readAll();
return true;
}
return false;
}
private:
QSerialPort * serial;
virtual void run()
{
mutex.lock();
QSerialPort port;
serial = &port;
port.setPortName("COM10");
port.open(QSerialPort::ReadWrite);
while (quit.tryLock()) {
quit.unlock();
if(!buffer.isEmpty())
{
serial->write(buffer);
buffer.clear();
if(serial->waitForReadyRead(1000))
{
emit onRead(serial->readAll());
}
else
emit onError();
}
mutex.unlock();
msleep(10);
mutex.lock();
}
}
signals:
void onError();
};
Re: Calling QSerialPort methods from two different threads
Quote:
Originally Posted by
egzi
so it should be perfectly safe to call syncWrite method from main thread
Only if you know for sure that none of the called code does anything thread specific.
Which seems not to be the case here.
You could implement the sync write in terms of doing an async write and then waiting for it to complete.
Btw, your async write is overwriting the shared buffer, if you call it twice in a row, only the second data packet will be sent.
Might be what you want of course.
Cheers,
_
Re: Calling QSerialPort methods from two different threads
Quote:
Originally Posted by
anda_skoa
You could implement the sync write in terms of doing an async write and then waiting for it to complete.
_
Then I would have to define variables which will hold results, some signaling method to wait for the results, its a pain in the ass and all that for each and every blocking method. That is how I will do that in the end, but I hoped for some more neat method. QT supposed to be easy threaded, but instead all those mechanisms just give me a headache. I have a feeling they are good just for incrementing ints (most examples on the net).
I wondered if I could use QTConcurrent::run and pass the thread in the thread pool. I will try when I get back my mood for qt programming.
Quote:
Originally Posted by
anda_skoa
Btw, your async write is overwriting the shared buffer, if you call it twice in a row, only the second data packet will be sent.
_
Yeah I know. It's just an example. Actually I have a blocking communication class which uses QSerialPort internally, that was easy to write. Now I want to implement an async methods but I want to have sync methods at the same time which leads me to the example-like wrapper which in turn gives me those error messages.
Thank you.
Re: Calling QSerialPort methods from two different threads
Quote:
Originally Posted by
egzi
Then I would have to define variables which will hold results
Depends.
If the calling thread can be allowed to further process events then it could "block" in a nested event loop.
Even when full blocking is required, it would mostly be a matter of chosing the "Task" structure accordingly.
Quote:
Originally Posted by
egzi
some signaling method to wait for the results
Binary semaphore. Acquire in caller, release in worker.
Cheers,
_