2012-10-15 57 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(); 
} 

希望这会有所帮助。

祝你好运。