Threading issues in C++

c++, multithreading, qt, qt4

Solution

First off all don't make the Systems singletons. Use some kind of Context Encapsulation for the different system.

If you ignoe this advice and still want to create "singletons" threads at least use `QApplication::instance();` as the parent of the thread and put `QThread::wait()` in the singleton destructors otherwise your program will crash at the program exit.

if(!s_instance){
    QMutexLocker lock(&mutex);
    if(!s_instance) 
        s_instance=new SensorProtocol( QApplication::instance());
} 

But this isn't going to solve your problem ... 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. Have a look at the blog entry from Bradley T. Hughes Treading without the headache

Code is not compiled but should give you a good idea where to start ...

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<DataPackage>();
    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(&protocolSystem, SIGNAL(dataReady(DataPackage)), SLOT(dataFromProtocol(DataPackage)));
    protocolSystem.connect(&gui, SIGNAL(start(int)), SLOT(start(int)));
    protocolSystem.connect(&gui, SIGNAL(stop()), SLOT(stop()));
    // move communication to its thread
    QThread protocolThread;
    protocolSystem.moveToThread(&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;    
}

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. 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, ...

Problem

I have asked this problem on many popular forums but no concrete response. My applciation uses serial communication to interface with external systems each having its own interface protocol. The data that is received from the systems is displayed on a GUI made in Qt 4.2.1. Structure of application is such that When app begins we have a login page with a choice of four modules. This is implemented as a maindisplay class. Each of the four modules is a separate class in itself. The concerned module here is of action class which is responsible of gathering and displaying data from various systems. User authentication gets him/her into the action screen. The constructor of the action screen class executes and apart from mundane initialisation it starts the individual systems threads which are implemented as singleton. Each system protocol is implemented as a singleton thread of the form: ``` class SensorProtocol:public QThread { static SensorProtocol* s_instance; SensorProtocol(){} SensorProtocol(const SensorProtocol&); operator=(const SensorProtocol&); public: static SensorProtocol* getInstance(); //miscellaneous system related data to be used for // data acquisition and processing }; ``` In implementation file *.cpp: ``` SensorProtocol* SensorProtocol::s_instance=0; SensorProtocol* SensorProtocol::getInstance() { //DOUBLE CHECKED LOCKING PATTERN I have used singletons // without this overrated pattern also but just fyi if(!s_instance) { mutex.lock(); if(!s_instance) s_instance=new SensorProtocol(); mutex.unlock(); } } ``` Structure of run function ``` while(!mStop) { mutex.lock() while(!WaitCondition.wait(&mutex,5) { if(mStop) return; } //code to read from port when data becomes available // and process it and store in variables mutex.unlock(); } ``` In the action screen class I have define an InputSignalHandler using sigaction and saio. This is a function pointer which is activated as soon as data arrives on any of the serial ports. It is a global function (we cannot change it as it is specific to Linux) which is just used to compare the file descriptors of the serial port where data has arrived and the fd's of the sensor systems, if a match is found WaitCondition.wakeOne is invoked on that thread and it comes out the wait and reads and processes the data. In the action screen class the individual threads are started as `SensorProtocol::getInstance()->start()`. Each system's protocol has a frame rate at which it sends data. Based on this fact, in actions screen we set up update timers to time out at refresh rate of protocols. When these timers time out the UpdateSensorProtocol() function of operation screen is called ``` connect(&timer, SIGNAL(timeout), this,SLOT(UpdateSensorProtocol())); ``` This grabs an instance of sensor singleton as ``` SensorProtocol* pSingleton=SensorProtocol::getInstance(); if(pSingleton->mUpdate) { //update data on action screen GUI pSingleton->mUpdate=false; //NOTE : this variable is set to // true in the singleton thread // while one frame is processed completely } ``` For all uses of singleton instance `SensorProtocol::getInstance()` is used. Given the above scenario, One of my protocols is hanging no matter what changes I do. The hang occurs in the while displaying data using UpdateSensorProtocol() If I comment `ShowSensorData()` function in the `UpdateSensorProtocol()` it works fine. But otherwise it hangs and the GUI freezes. Any suggestions! Also, Since the main thread grabs the running instance of singleton, is it really multithreading because we are essentially changing mUpdate in singleton itself albeit from action screen. I am confused in this. Also, Can somebody suggest an alternate design as to what I am doing now. Thanks In Advance

Original source