简体   繁体   English

线程实现为单例

[英]Thread implemented as a Singleton

I have a commercial application made with C,C++/Qt on Linux platform. 我在Linux平台上有一个用C,C ++ / Qt制作的商业应用程序。 The app collects data from different sensors and displays them on GUI. 该应用程序从不同的传感器收集数据并将其显示在GUI上。 Each of the protocol for interfacing with sensors is implemented using singleton pattern and threads from Qt QThreads class. 使用Qt QThreads类的单例模式和线程来实现与传感器接口的每种协议。 All the protocols except one work fine. 除了一个协议之外的所有协议都可以正常工作。 Each protocol's run function for thread has following structure: 每个协议的线程运行函数具有以下结构:

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
}

Hierarchy of GUI. GUI的层次结构。

1.Login screen. 1.登录画面 2. Screen of action. 2.行动屏幕。

When a user logs in from login screen, we enter the action screen where all data is displayed and all the thread's for different sensors start. 当用户从登录屏幕登录时,我们进入操作屏幕,在该屏幕上显示所有数据,并启动用于不同传感器的所有线程。 They wait on mStop variable in idle time and when data arrives they jump to receiving and processing data. 他们在空闲时间等待mStop变量,当数据到达时,它们跳转到接收和处理数据。 Incoming data for the problem protocol is 117 bytes. 问题协议的传入数据为117字节。 In the main GUI threads there are timers which when timeout, grab the running instance of protocol using 在主GUI线程中有计时器,这些计时器在超时时使用以下命令获取正在运行的协议实例

   <ProtocolName>::instance() function

Check the update variable of singleton class if its true and display the data. 检查单例类的更新变量是否为true并显示数据。 When the data display is done they reset the update variable in singleton class to false. 完成数据显示后,他们将单例类中的更新变量重置为false。 The problematic protocol has the update time of 1 sec, which is also the frame rate of protocol. 有问题的协议的更新时间为1秒,这也是协议的帧速率。 When I comment out the display function it runs fine. 当我注释掉显示功能时,它运行良好。 But when display is activated the application hangs consistently after 6-7 hours. 但是,激活显示后,应用程序会在6-7小时后始终挂起。 I have asked this question on many forums but haven't received any worthwhile suggestions. 我在很多论坛上都问过这个问题,但没有收到任何有价值的建议。 I Hope that here I will get some help. 希望在这里能得到一些帮助。 Also, I have read a lot of literature on Singleton, multithreading, and found that people always discourage the use of singletons especially in C++. 另外,我阅读了很多有关单例,多线程的文献,发现人们总是不鼓励使用单例,尤其是在C ++中。 But in my application I can think of no other design for implementation. 但是在我的应用程序中,我认为没有其他设计可以实现。

Thanks in advance 提前致谢

A Hapless programmer 没经验的程序员

I think singleton is not really what you are looking for. 我认为单身人士并不是您真正想要的。 Consider this: 考虑一下:

You have (lets say) two sensors, each with its own protocol (frame rate, for our purpose). 您(假设)有两个传感器,每个传感器都有自己的协议(出于我们的目的,使用帧速率)。

Now create "server" classes for each sensor instead of an explicit singleton. 现在为每个传感器创建“服务器”类,而不是显式的单例。 This way you can hide the details of how your sensors work: 这样,您可以隐藏传感器工作方式的详细信息:

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);
    }
}

This way you can do away with having to implement a singleton. 这样,您就不必实施单例。

Cheers, 干杯,

jrh. JRH。

Just a drive-by analysis but this doesn't smell right. 只是一个过客分析,但这听起来不对。

If the application is "consistently" hanging after 6-7 hours are you sure it isn't a resource (eg memory) leak? 如果应用程序在6到7个小时后“始终如一”地挂起,您确定它不是资源(例如内存)泄漏吗? Is there anything different about the implementation of the problematic protocol from the rest of them? 问题协议的实现与其他协议有什么不同? Have you run the app through a memory checker, etc.? 您是否通过内存检查器等运行该应用程序?

Not sure it's the cause of what you're seeing, but you have a big fat synchronization bug in your code: 不知道这是您所看到的原因,但是您的代码中存在一个严重的同步错误:

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
}

better: 更好:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM