Al2O3
Al2O3

Reputation: 3203

Program still crashes after using mutex(can i use mutex in the same thread?)

I created two threads, and use mutex to synchronize them.
In the mainwindow program(which i regard as the main thread) in which the other thread is created, I have to use mutex in at least two functions, because one is a slot to accept signals from UI when user selects a menu and configure the data, and there is also a timer which runs out 1 time per sec and triggers a slot function which reads the data.

My program often crashes even i use mutex. In 'main thread' there are different functions which have mutex's lock and unlock operations, one of the functions is a slot linked to the timer. Also the other thread continuously writes the data.

I am so confused, why ?
(:) I really need a better phone to edit my question before this time :) )

My code:
In thread:

class Background : public QThread
{
    Q_OBJECT

public:
    void Background::run(void)
    {
        initFile();

        while(1)
        {

            Mutex->lock();
            msleep(40);
            rcv();          //writes map here
            Mutex->unlock();

        }

    }
...
}

In thread's rcv():

void Background::rcv()
{
    DEVMAP::iterator dev_r;

    for(dev_r= DevMap.begin(); dev_r!= DevMap.end(); dev_r++)//DevMap is a refrence to the dev_map in mainwindow.
    {
       ...  ....//writes the map

    }
}

In mainwindow:

void MainWindow::initTimer()
{
    refreshTimer = new QTimer(this);
    connect(refreshTimer, SIGNAL(timeout()), this, SLOT(refreshLogDisplay()));
    refreshTimer->start(1000);
}

void MainWindow::refreshLogDisplay()
{

//MUTEX
    mutex->lock();

    ......//read the map

//MUTEX
    mutex->unlock();

}

In the thread's construction:

Background(DEVMap& map,...,QMutex* mutex):DevMap(map)...,Mutex(mutex){}

In mainwindow which creates the thread:

void MainWindow::initThread()
{


    mutex = new QMutex;
    back = new Background(dev_map,..., mutex);
    back->start();

}

And:

void MainWindow::on_Create_triggered()//this function is a slot triggered by a menu item in the MainWindow UI
{

    ......//get information from a dialog 


//MUTEX

    mutex->lock();

    BitState* bitState = new BitState(string((const char *)dlg->getName().toLocal8Bit()),
                                        string((const char *)dlg->getNO().toLocal8Bit()),
                                      dlg->getRevPortNo().toInt(), dlg->getSndPortNo().toInt());


    dev_map.insert(DEVMAP::value_type (string((const char *)dlg->getPIN().toLocal8Bit()), *bitState)); 
     //writes map here



//MUTEX
     mutex->unlock();


}

Upvotes: -1

Views: 1199

Answers (1)

ChatCloud
ChatCloud

Reputation: 1200

You can use mutex in any thread. It was designed for this purposes. But you should not create dead locks, for instance if you do 'nested' calls of the 'lock'.

Good:

mutex->lock();
//code
mutex->unlock();
//code
mutex->lock();
//code
mutex->unlock();

Bad:

mutex->lock();
//code
mutex->lock(); //dead lock
//code
mutex->unlock();
//code
mutex->unlock();

Be accurate when using locks in functions:

void foo()
{
mutex->lock();
//code
mutex->unlock();
}

mutex->lock();
foo(); //dead lock
mutex->unlock()

Also you need to lock as less code as possible. Placing sleep() inside the lock is not not a good idea as far other threads will wait while it's sleeping.

Not good:

while(1)
{
  Mutex->lock();
  msleep(40);
  rcv();
  Mutex->unlock();
}

Better:

while(1)
{
  msleep(40);
  Mutex->lock();
  rcv();
  Mutex->unlock();
}

Upvotes: 2

Related Questions