我有一个商业应用程序用C,C++/Qt在Linux平台上。该应用程序从不同的传感器收集数据,并将其显示在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检查单例类的更新变量是否为真,并显示数据。当数据显示完成后,它们将singleton类中的update变量重置为false。问题协议的更新时间为1秒,这也是协议的帧率。当我注释掉display函数时,它运行得很好。但当display被激活时,应用程序会在6-7小时后持续挂起。我已经在许多论坛上问过这个问题,但没有收到任何有价值的建议。我希望在这里我能得到一些帮助。此外,我还阅读了大量关于单例、多线程的文献,发现人们总是不鼓励使用单例,尤其是在C++中。但在我的应用程序中,我想不出其他的实现设计。
提前感谢
一个倒霉的程序员
发布于 2009-06-22 05:39:51
我认为单例并不是你真正想要的。请考虑以下内容:
您有(比方说)两个传感器,每个传感器都有自己的协议(我们的目的是帧速率)。
现在为每个传感器创建"server“类,而不是显式的单例。这样,您可以隐藏传感器工作方式的详细信息:
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。
发布于 2009-06-22 06:05:00
只是路过分析,但这闻起来不对劲。
如果应用程序在6-7小时后“持续”挂起,您确定这不是资源(例如内存)泄漏吗?问题协议的实现与其他协议有什么不同吗?你有没有通过内存检查器等来运行应用程序?
发布于 2009-07-20 09:03:44
我不确定这是你所看到的原因,但是你的代码中有一个很大的同步错误:
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
}https://stackoverflow.com/questions/1025511
复制相似问题