2009-06-22 2 views
0

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, multithreading에 대한 많은 문헌을 읽었으며 특히 C++에서 사람들이 항상 싱글 톤 사용을 꺼리는 것을 발견했습니다. 그러나 제 신청에서 구현을위한 다른 설계는 생각할 수 없습니다. 사전

불운 한 프로그래머

+0

당신이 명확히 할 필요가 별도의 스레드로 구현 되었습니까? 스레드는 어디에 살고 있습니까? GUI에서? 센서에? 중앙 서버에서? 누가 스레드에 액세스합니까? 스레드가 액세스하는 동일한 앱에 스레드가 있습니까? – jrharshath

+0

단일 응용 프로그램입니다. 각 센서에는 인터페이스와 프로토콜 및 프레임 속도가 있습니다. 따라서 각 프로토콜은 단일 스레드로 구현됩니다. 스레드는 사용자가 인증되고 작업 화면을 시작할 때 시작됩니다. 각 프로토콜 스레드는 기본 GUI THREAD 클래스의 구성원입니다. 프레임 속도를 기반으로 우리는 GUI 쓰레드에서 동등한 타이머를 설정합니다. GUI 쓰레드가 타임 아웃하면 프로토콜 인스턴스를 잡고 프로토콜 클래스의 업데이트 변수를 기반으로 데이터를 표시합니다. GUI에서 데이터를 업데이트 한 후이 변수를 false로 재설정합니다. 이 업데이트 변수는 각 프로 토크의 구성원입니다 – rocknroll

답변

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

당신이 싱글 톤을 구현하는 데 멀리 할 수있는이 방법을.

건배,

주니어.

+0

GUI의 위젯에이 값을 표시해야하고 센서 프로토콜이 GUI 스레드 클래스의 구성원이므로 프로토콜 클래스 핸들을 사용하여 멤버에 액세스해야합니까? 또한 들어오는 데이터에 대한 프로토콜 스레드에 알리기 위해 직렬 인터럽트 (serial port)에서 입력을 수신 할 때 적절한 스레드를 깨우는 전역 인터럽트 핸들러 (Linux의 유일한 방법 인 sigaction 및 sigio 신호 처리기를 사용할 수있는 유일한 방법)를 사용했습니다. 이 시나리오에서는 뭔가 제안 할 수 있습니다. 생각해 볼 다른 관점을 주셔서 대단히 감사합니다. 하지만 난 아직도이 디자인이 내 애플 리케이션에 맞는 것입니다에 대한 명확하지 않다 – rocknroll

0

그냥 드라이브 바이 분석이지만이 냄새는 없습니다.

응용 프로그램이 6-7 시간 후에 "지속적으로 매달려"있는 경우 리소스 (예 : 메모리) 누출이 아닌 것이 확실합니까? 문제가있는 프로토콜의 구현과 다른 점이 있습니까? 메모리 검사기 등을 통해 앱을 실행 했습니까?

+0

나는 애플 리케이션을 확인하지 못했지만 그 메모리 사용이 꾸준히 증가 관찰했다. 처음에는 175MB이고 하루가 지나면 300MB로 증가합니다. 그러나 이것은 gnome-system-monitor 또는 top cmd를 사용하여 전체 시스템을 검사 할 때입니다. 시스템은 테스트 중에 사용되지 않습니다. 또한 핵심 구현은 위에서 언급 한 것과 동일하며 데이터 관련 구현이 변경됩니다. – rocknroll

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 
} 
관련 문제