Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>First off all don't make the Systems singletons. Use some kind of <a href="http://www.two-sdg.demon.co.uk/curbralan/papers/europlop/ContextEncapsulation.pdf" rel="nofollow noreferrer">Context Encapsulation </a> for the different system.</p> <p>If you ignoe this advice and still want to create "singletons" threads at least use <code>QApplication::instance();</code> as the parent of the thread and put <code>QThread::wait()</code> in the singleton destructors otherwise your program will crash at the program exit. </p> <pre><code>if(!s_instance){ QMutexLocker lock(&amp;mutex); if(!s_instance) s_instance=new SensorProtocol( QApplication::instance()); } </code></pre> <p>But this isn't going to solve your problem ...<br> Qt is event driven so try to exployed this very nice event-driven architecture and create a eventloop for each system thread. Then you can create "SystemProtocols" that live in another threads and you can create timers, send events between threads, ... without using low level synchronization objects. <br> Have a look at the blog entry from Bradley T. Hughes <a href="http://labs.trolltech.com/blogs/2006/12/04/threading-without-the-headache/" rel="nofollow noreferrer">Treading without the headache</a></p> <p>Code is not compiled but should give you a good idea where to start ...</p> <pre><code>class GuiComponent : public QWidget { //... signals: void start(int); // button triggerd signal void stop(); // button triggerd singal public slots: // don't forget to register DataPackage at the metacompiler // qRegisterMetaType&lt;DataPackage&gt;(); void dataFromProtocol( DataPackage ){ // update the gui the the new data } }; class ProtocolSystem : public QObject { //... int timerId; signals: void dataReady(DataPackage); public slots: void stop() { killTimer(timerId); } void start( int interval ) { timerId = startTimer(); } protected: void timerEvent(QTimerEvent * event) { //code to read from port when data becomes available // and process it and store in dataPackage emit dataReady(dataPackage); } }; int main( int argc, char ** argv ) { QApplication app( argc, argv ); // construct the system and glue them together ProtocolSystem protocolSystem; GuiComponent gui; gui.connect(&amp;protocolSystem, SIGNAL(dataReady(DataPackage)), SLOT(dataFromProtocol(DataPackage))); protocolSystem.connect(&amp;gui, SIGNAL(start(int)), SLOT(start(int))); protocolSystem.connect(&amp;gui, SIGNAL(stop()), SLOT(stop())); // move communication to its thread QThread protocolThread; protocolSystem.moveToThread(&amp;protocolThread); protocolThread.start(); // repeat this for other systems ... // start the application gui.show(); app.exec(); // stop eventloop to before closing the application protocolThread.quit(); protocolThread.wait(); return 0; } </code></pre> <p>Now you have total independent systems, gui and protocols don't now each other and don't even know that the program is multithreaded. You can unit test all systems independently in a single threaded environement and just glue them together in the real application and if you need to, divided them between different threads. <br> That is the program architecture that I would use for this problem. Mutlithreading without a single low level synchronization element. No race conditions, no locks, ...</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload