线程实现为Singleton

时间:2009-06-22 04:57:29

标签: c++ multithreading singleton

我在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程序员

3 个答案:

答案 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
}