2012-10-15 56 views
0

我有具有UI與用戶選擇顯示方式,做一個小型系統配置程序。它也有一個後臺程序,它不斷從網絡讀取數據並更新數據以顯示。我應該使用CRITICAL_SECTION嗎?

現在我把它們放在一個過程: 後臺程序:

STATE MainWindow::Rcv() 
    { 

    DeviceMAP::iterator dev; 

    for(dev= dev_map.begin(); dev!= dev_map.end(); dev++) 
    { 


     dev->second.rcvData();//receive data from the network, the time can be ignored. 

     BitLog* log = new BitLog(); 
     dev->second.parseData(log); 


     LogItem* logItem = new LogItem(); 
     logItem->time = QString::fromLocal8Bit(log->rcvTime.c_str()); 
     logItem->name = QString::fromLocal8Bit(log->basicInfo.getName().c_str()); 
     logItem->PIN = QString::fromLocal8Bit(log->basicInfo.getPIN().c_str()).toShort(); 

     delete log; 
     add_logItem(logItem); 

    } 
    return SUCCESS; 
} 

add_logItem:

void MainWindow::add_logItem(LogItem* logItem) 
{ 


    writeToFile(logItem); 

    Device* r = getDevbyPIN(QString::number(logItem->PIN)); 

    if(r == NULL)return; 

    devInfo_inside_widget::States state = logItem->state; 

    bool bool_list[portsNum_X]; 
    for(int i =0; i < portsNum_X; i++) 
    { 
     bool_list[i] = 0; 
    } 

    for(int i = 0; i < portsNum; i++) 
    { 
     bool_list[i] = (logItem->BITS[i/8] >> (7 - i%8)) & 0x1; 
    } 

    r->refresh(state, logItem->time, bool_list);//update data inside...state, time , BITS... 

    IconLabel* icl = getIConLabelByDev(r);//update data 
    icl->refresh(state); 


    logDisplayQueue.enqueue(logItem);//write queue here 

    int size = logDisplayQueue.size(); 

    if(size > 100) 
    { 
     logDisplayQueue.dequeue();//write queue here 
    } 

} 

的部分上面並沒有涉及任何的UI操作呢,但是當用戶按下一個無線電在UI按鈕,程序具有在隊列中來篩選數據,並在表格部件顯示它:

UI操作:

void MainWindow::filter_log_display(bool bol) 
{ 

    row_selectable = false; 
    ui->tableWidget->setRowCount(0);//delete table items all 
    row_selectable = true; 

    int size_1 = logDisplayQueue.size() - 1; 

    ui->tableWidget->verticalScrollBar()->setSliderPosition(0); 

    if(size_1+1 < 100) 
    { 
     ui->tableWidget->setRowCount(size_1 + 1); 
    } 
    else 
    { 
     ui->tableWidget->setRowCount(100);//display 100 rows at most 
    } 


    if(bol)//filter from logDisplayQueue and display unworking-state-log rows 
    { 

     int index = 0; 
     for(int queue_i = size_1; queue_i >= 0; queue_i--) 
     { 

      LogItem* logItem = (LogItem*)logDisplayQueue.at(queue_i); // read queue here 

      if(logItem->state == STATE_WORK || logItem->state == STATE_UN)continue; 


      QString BITS_str = bits2Hexs(logItem->BITS); 

      ui->tableWidget->setItem(index, 0, new QTableWidgetItem(logItem->time));//time 
      ui->tableWidget->setItem(index, 1, new QTableWidgetItem(logItem->name));//name 
      ui->tableWidget->setItem(index, 2, new QTableWidgetItem(BITS_str));//BITS 

      if(queue_i == oldRowItemNo)ui->tableWidget->selectRow(index); 
      index++; 
     } 

     ui->tableWidget->setRowCount(index); 

    } 
    else//display all rows 
    { 

     for(int queue_i = size_1, index = 0; queue_i >= 0; queue_i--, index++) 
     { 

      LogItem* logItem = (LogItem*)logDisplayQueue.at(queue_i);      //read queue here 

      QString BITS_str = bits2Hexs(logItem->BITS);// 
      finish = clock(); 

      ui->tableWidget->setItem(index, 0, new QTableWidgetItem(logItem->time));//time 
      ui->tableWidget->setItem(index, 1, new QTableWidgetItem(logItem->name));//name 
      ui->tableWidget->setItem(index, 2, new QTableWidgetItem(BITS_str));//BITS 

      if(queue_i == oldRowItemNo)ui->tableWidget->selectRow(index); 

     } 



    } 

} 

所以隊列很小,後臺程序非常頻繁(每秒近500次)。也就是說,隊列將在1秒內寫入500次,但用戶顯示時間。
我想要的功能分成兩個線程並一起運行,一個轉和更新數據,一個顯示器。
如果我不使用任何鎖或互斥,用戶可以得到錯誤的數據,但如果我強迫寫數據的過程進入臨界區,離開臨界區,每次,這將是一個沉重的過載。 :)
我應該使用CRITICAL_SECTION或別的東西,相關的有什麼建議?(我說的話可能是詳細爲你:),我只希望獲得一些提示:)

回答

2

我把「接收」功能在其他的QObject派生類,把它放在其他QThread不是主要的gui線程,並將「logItemAdded(LogItem * item)」信號連接到主窗口的「addLogItem(LogItem * item)」插槽。

只是快速和骯髒的暗示我的概念代碼如下。

#include <QObject> 

class Logger : public QObject 
{ 
    Q_OBJECT 
public: 
    Logger(QObject* parent=0); 
    virtual ~Logger(); 
signals: 
    void logItemAdded(LogItem* logItem); 
public slots: 
protected: 
    void Rcv() 
    { 
     // ... 

     // was "add_logItem(logItem)" 
     emit logItemAdded(logItem); 
    } 
}; 

MainWindow::MainWindow(...) 
{ 
    Logger logger = new Logger; 

    // setup your logger 

    QThread* thread = new QThread; 
    logger->moveToThread(thread); 
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); 
    thread->start(); 
} 

希望這會有所幫助。

祝你好運。