[Qt-interest] Basic QThread question

Sean Harmer sean.harmer at maps-technology.com
Wed May 19 10:13:13 CEST 2010


On Tuesday 18 May 2010 08:34:46 Phil wrote:
<snip>
> This is exactly what I'm doing but the hardware has many write functions
> besides a data reading function. I'm attempting to write to the hardware
> from the main thread which intermittently conflicts with the read from the
> DevicePoller thread. Precisely the simultaneous access condition that you
> mentioned above.
> 
> > It is difficult to say which approach is better for you without knowing
> > 
> >  what Class_A actually does and how long the Class_A::getIntitialValues()
> >  and getData() functions take. If possible I would go with the second
> >  option as it removes the possibility of concurrency issues within
> >  Class_A.
> 
> Before receiving your reply Sean I was nearing the point of giving up on
> threads and going back to my GUI blocking version. It seems to me that I
> need to combine the hardware's write functions, which are currently
> members of the main class, and the read function into your DevicePoller
> class. I'm unsure just how I might access the write functions from the main
> class without causing a simultaneous access condition. The best that I come
> up with is:
> 
> if(OkToRead)
>     readDevice();
> 
> > No problem. If you still run into trouble, come back with more details on
> > Class_A.
> 
> I'm hesitant to burden the other list members with this seemingly never
> ending saga. I'll see if I can approach this problem from a different
> angle.

Right, the important piece of information that you missed out was that Class_A 
is what actually communicates with your device and that both threads are 
trying to do so. 

If the communication with this device can potentially block, then I would move 
the classA object into the thread and have all comms performed in the worker 
thread. After all the DevicePoller class is simply a wrapper around a timer 
and what I thought was going to be a few simple calls to talk to your device. 
Just replace or augment the DevicePoller object with something that meets your 
needs. 

This way the polling timer will not cause a conflict because if you are in the 
middle of communicating with your device in a blocking manner in the worker 
thread, then the timer that triggers the polling will not fire until you 
return to the event loop. You can easily pass information/requests to/from the 
main main thread via the signal-slot mechanism.

The above method is essentially the blocking method that you had originally 
but all the parts that can block are now in a worker thread rather than the 
main GUI thread and so should be relatively simple to achieve.

Another thought, why do your communications to the device block at all? What 
type of connection do you have to your device? Qt makes it easy to perform 
non-blocking IO without the need for threads. We have similar objects that 
perform such comms (using QextSerialPort or QTcpSocket) which do not block - 
although we do move these objects into their own thread for other reasons. 
This method sounds like it would be more work given the current blocking 
design of your Class_A.

So in summary, two basic options:

(1) Move the one and only instance of Class_A into the worker thread and pass 
info/requests to/from the main thread using signals/slots. Class_A does not 
need to be changed and should be quite simple to do.

(2) Re-implement Class_A so that it uses non-blocking comms. More work but 
potentially allows you to not need to use threads at all.

I would personally go for option (1) in the short term with a view to possibly 
implementing option (2) later as this would for example allow you to 
communicate with several devices from within the same thread without blocking 
each other.

HTH,

Sean



More information about the Qt-interest-old mailing list