我在Linux平台上使用C,C ++ / Qt制作了商业应用程序。该应用程序从不同的传感器收集数据并在GUI上显示。用于与传感器接口的每个协议都是使用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
检查单例类的更新变量是否为true,并显示数据。完成数据显示后,他们将singleton类中的update变量重置为false。有问题的协议的更新时间为1秒,这也是协议的帧速率。当我注释掉显示功能时它运行正常。但是,当激活显示时,应用程序会在6-7小时后持续挂起。我在很多论坛上都提过这个问题,但没有得到任何有价值的建议。我希望在这里我会得到一些帮助。另外,我已经阅读了很多关于Singleton,多线程的文献,并发现人们总是不鼓励使用单例,特别是在C ++中。但在我的应用程序中,我认为没有其他设计可供实现。
提前致谢
一个Hapless程序员
答案 0 :(得分:2)
我认为单身并不是你想要的。考虑一下:
你有(比方说)两个传感器,每个传感器都有自己的协议(帧率,为了我们的目的)。
现在为每个传感器创建“服务器”类,而不是显式单例。这样,您可以隐藏传感器工作方式的详细信息:
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。
答案 1 :(得分:0)
只是一个偷渡式的分析,但这闻不到。
如果应用程序在6-7小时后“始终”挂起,您确定它不是资源(例如内存)泄漏吗?其余的问题协议的实施有什么不同吗?您是否通过内存检查器等运行应用程序?
答案 2 :(得分:0)
不确定这是你所看到的原因,但你的代码中有一个很大的同步错误:
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
}