我在许多流行的论坛上问过这个问题,但没有具体的回应。我的应用程序使用串行通信与外部系统连接,每个系统都有自己的接口协议。从系统接收的数据显示在 Qt 4.2.1 中制作的 GUI 上。
应用程序的结构是这样的
当应用程序启动时,我们有一个登录页面,其中有四个模块可供选择。这是作为 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();
}
在动作屏幕类中,我使用 sigaction 和 saio 定义了 InputSignalHandler。这是一个函数指针,一旦数据到达任何串行端口,它就会被激活。
它是一个全局函数(我们无法更改它,因为它特定于 Linux),它仅用于比较数据到达的串行端口的文件描述符和传感器系统的 fd,如果找到匹配项 WaitCondition.wakeOne在该线程上调用,它会等待并读取和处理数据。
在动作屏幕类中,各个线程以SensorProtocol::getInstance()->start()
.
每个系统的协议都有一个发送数据的帧速率。基于这一事实,在操作屏幕中,我们设置了更新计时器以在协议刷新率时超时。当这些计时器超时时,调用操作屏幕的 UpdateSensorProtocol() 函数
connect(&timer, SIGNAL(timeout), this,SLOT(UpdateSensorProtocol()));
这会抓取一个传感器单例实例作为
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()
它工作正常。但否则它会挂起并且 GUI 冻结。有什么建议么!
此外,由于主线程抓取了单例的运行实例,它真的是多线程的吗,因为我们本质上是在单例本身中更改 mUpdate,尽管是从动作屏幕开始的。
我对此感到困惑。
另外,有人可以建议我现在正在做什么的替代设计。
提前致谢