2013年9月2日 星期一

QMutex的妙用


困擾多時的crash bug終於找到原因,若是有多個thread或event handler同時去執行QMap.remove(),就會對這個QMap造成錯亂,若下次要再使用它時,就會crash。

example:

QMap<int, QString> myMap;

void myQThread1()
{
    ......
    /* 正常而言,QMap.remove()回傳值ret應是1,
        若有兩個thread同時執行到這行,會發現ret的值會變成2
    */
    int ret = myMap.remove(key);
    ......
}

void setNameMap()
{
    ......
    //這時若再insert資料進去,就會產生錯誤
    myMap.insert(key, value);
    ......
}


解決的方法很簡單,加上QMutex就可以了:

QMutex mutex;
void myQThread1()
{
    ......
    mutex.lock();
    int ret = myMap.remove(key);
    mutex.unlock();
    ......
}

如此一來,當某一個thread已經進入lock之後,另一個thread就無法去remove QMap的值,要等到前一個thread的mutex.unlock()之後才行。

可以的話,也能在QMap.insert()時加上qmutex,以避免同時寫入所產生的問題。