Нить реализована как синглтон - PullRequest
0 голосов
/ 22 июня 2009

У меня есть коммерческое приложение, созданное на C, C ++ / Qt на платформе Linux. Приложение собирает данные с разных датчиков и отображает их в графическом интерфейсе. Каждый из протоколов взаимодействия с датчиками реализован с использованием одноэлементного шаблона и потоков из класса Qt QThreads. Все протоколы, кроме одного, работают нормально. Каждая функция запуска протокола для потока имеет следующую структуру:

void <ProtocolClassName>::run()
{
while(!mStop)  //check whether screen is closed or not
{

mutex.lock()
  while(!waitcondition.wait(&mutex,5))
  {
   if(mStop)
      return;
  }

  //Code for receiving and processing incoming data

 mutex.unlock();
} //end while
}

Иерархия GUI.

1.Вход на экран. 2. Экран действий.

Когда пользователь входит в систему с экрана входа в систему, мы открываем экран действий, где отображаются все данные и запускаются все потоки для разных датчиков. Они ждут переменную mStop во время простоя, а когда данные поступают, они переходят к получению и обработке данных. Входящие данные для протокола проблемы составляют 117 байтов. В основных потоках GUI есть таймеры, которые по истечении времени ожидания захватывают запущенный экземпляр протокола, используя

   <ProtocolName>::instance() function

Проверьте переменную обновления одноэлементного класса, если она истинна, и отобразите данные. Когда отображение данных завершено, они сбрасывают переменную обновления в синглтон-классе на false. Проблемный протокол имеет время обновления 1 с, что также является частотой кадров протокола. Когда я закомментирую функцию отображения, она работает нормально. Но при включенном дисплее приложение зависает стабильно через 6-7 часов. Я задавал этот вопрос на многих форумах, но не получил достойных предложений. Надеюсь, что здесь мне помогут. Кроме того, я прочитал много литературы по Singleton, многопоточности, и обнаружил, что люди всегда препятствуют использованию синглетонов, особенно в C ++. Но в моем приложении я не могу представить никакой другой дизайн для реализации.

Заранее спасибо

Несчастный программист

Ответы [ 3 ]

2 голосов
/ 22 июня 2009

Я думаю, что синглтон не совсем то, что вы ищете. Учтите это:

У вас есть (скажем, два) датчика, каждый с собственным протоколом (частота кадров для нашей цели).

Теперь создайте «серверные» классы для каждого датчика вместо явного синглтона. Таким образом, вы можете скрыть детали того, как работают ваши датчики:

class SensorServer {
protected:
   int lastValueSensed;
   QThread sensorProtocolThread;
public:
   int getSensedValue() { return lastValueSensed; }
}

class Sensor1Server {
public: 
   Sensor1Server() {
        sensorProtocolThread = new Sensor1ProtocolThread(&lastValueSensed);
        sensorProtocolThread.start();
   }
}

class Sensor1ProtocolThread : public QThread {
protected:
    int* valueToUpdate;
    const int TIMEOUT = 1000; // "framerate" of our sensor1
public:
    Sensor1ProtocolThread( int* vtu ) {
        this->valueToUpdate = vtu;
    }
    void run() {
        int valueFromSensor;
        // get value from the sensor into 'valueFromSensor'
        *valueToUpdate = valueFromSensor;
        sleep(TIMEOUT);
    }
}

Таким образом, вы можете покончить с необходимостью реализации синглтона.

Приветствия

JRH.

0 голосов
/ 20 июля 2009

Не уверен, что это причина того, что вы видите, но в вашем коде есть большая жирная ошибка синхронизации:

void <ProtocolClassName>::run()
{
    while(!mStop)  //check whether screen is closed or not
    {

        mutex.lock()
        while(!waitcondition.wait(&mutex,5))
        {
            if(mStop)
                return; // BUG: missing mutex.unlock()
        }

        //Code for receiving and processing incoming data

        mutex.unlock();
    } //end while
}

лучше:

void <ProtocolClassName>::run()
{
    while(!mStop)  //check whether screen is closed or not
    {
        const QMutexLocker locker( &mutex );
        while(!waitcondition.wait(&mutex,5))
        {
            if(mStop)
                return; // OK now
        }

        //Code for receiving and processing incoming data

    } //end while
}
0 голосов
/ 22 июня 2009

Просто анализ на ходу, но это не пахнет правильно.

Если приложение «постоянно» зависает через 6-7 часов, вы уверены, что это не утечка ресурса (например, памяти)? Есть ли что-то отличное в реализации проблемного протокола от остальных? Вы запускаете приложение через проверку памяти и т. Д.? 1003 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...