Я задавал эту проблему на многих популярных форумах, но не дал конкретного ответа. Мое приложение использует последовательную связь для взаимодействия с внешними системами, каждая из которых имеет свой собственный протокол интерфейса. Данные, полученные от систем, отображаются в графическом интерфейсе, созданном в Qt 4.2.1.
Структура приложения такова, что
Когда приложение начинается, у нас есть страница входа
с выбором из четырех модулей. это
реализован как maindisplay
учебный класс. Каждый из четырех модулей является
отдельный класс сам по себе. Данный модуль относится к классу действий, отвечающему за сбор и отображение данных из различных систем.
Аутентификация пользователя получает его / ее
в экран действий.
конструктор экрана действий
класс выполняется и кроме
мирская инициализация запускает
отдельные системные потоки, которые
реализовано как синглтон.
Каждый системный протокол реализован в виде одноэлементного потока в форме:
class SensorProtocol:public QThread {
static SensorProtocol* s_instance;
SensorProtocol(){}
SensorProtocol(const SensorProtocol&);
operator=(const SensorProtocol&);
public:
static SensorProtocol* getInstance();
//miscellaneous system related data to be used for
// data acquisition and processing
};
В файле реализации * .cpp:
SensorProtocol* SensorProtocol::s_instance=0;
SensorProtocol* SensorProtocol::getInstance()
{
//DOUBLE CHECKED LOCKING PATTERN I have used singletons
// without this overrated pattern also but just fyi
if(!s_instance)
{
mutex.lock();
if(!s_instance)
s_instance=new SensorProtocol();
mutex.unlock();
}
}
Структура функции запуска
while(!mStop)
{
mutex.lock()
while(!WaitCondition.wait(&mutex,5)
{
if(mStop)
return;
}
//code to read from port when data becomes available
// and process it and store in variables
mutex.unlock();
}
В классе экрана действий я определил InputSignalHandler, используя sigaction и saio. Это указатель на функцию, который активируется, как только данные поступают на любой из последовательных портов.
Это глобальная функция (мы не можем ее изменить, поскольку она специфична для Linux), которая используется только для сравнения файловых дескрипторов последовательного порта, куда поступили данные, и файловых систем сенсорных систем, если найдено совпадение WaitCondition.wakeOne вызывается в этом потоке, и он выходит из режима ожидания, считывает и обрабатывает данные.
В классе экрана действий отдельные потоки запускаются как SensorProtocol::getInstance()->start()
.
Протокол каждой системы имеет частоту кадров, с которой он отправляет данные. Исходя из этого, на экране действий мы настроили таймеры обновления на тайм-аут с частотой обновления протоколов. Когда время этих таймеров истекает, функция UpdateSensorProtocol () экрана операции вызывается
connect(&timer, SIGNAL(timeout), this,SLOT(UpdateSensorProtocol()));
Это захватывает экземпляр датчика singleton как
SensorProtocol* pSingleton=SensorProtocol::getInstance();
if(pSingleton->mUpdate)
{
//update data on action screen GUI
pSingleton->mUpdate=false; //NOTE : this variable is set to
// true in the singleton thread
// while one frame is processed completely
}
Для всех применений синглтона используется экземпляр SensorProtocol::getInstance()
. Учитывая вышеописанный сценарий, один из моих протоколов зависает независимо от того, какие изменения я делаю.
Зависание происходит при отображении данных с помощью UpdateSensorProtocol (). Если я прокомментирую функцию ShowSensorData()
в UpdateSensorProtocol()
, она работает нормально. Но в противном случае он зависает и графический интерфейс пользователя зависает. Любые предложения!
Кроме того, поскольку основной поток захватывает запущенный экземпляр singleton, действительно ли это многопоточность, потому что мы существенно меняем mUpdate в самом синглтоне, хотя и с экрана действия.
Я запутался в этом.
Кроме того, может кто-нибудь предложить альтернативный дизайн относительно того, что я делаю сейчас.
Заранее спасибо