2017-09-21 20 views
0

QtConcurrent을 사용하여 동시에 함수를 실행하려고하는데 인수 중 하나와 관련된 문제가 발생합니다.QtConcurrent :: run - 포인터 전달 문제

class DataMessage : public QObject { 
    Q_OBJECT 
    // ... fields and methods 
}; 

class ITimeStampInfo { 
    public: 
     virtual QDateTime timestamp() const = 0; 
}; 
Q_DECLARE_INTERFACE(ITimeStampInfo, "My.TimeStampInfo/1.0") 

class IDataLengthInfo { 
    public: 
     virtual int dataLength() const = 0; 
}; 
Q_DECLARE_INTERFACE(IDataLengthInfo, "My.IDataLengthInfo/1.0") 

class DataMessage1 : public DataMessage, public ITimeStampInfo { 
    Q_OBJECT 
    Q_INTERFACES(ITimeStampInfo) 
    // other fields, etc 
    QDateTime timestamp() const; 
}; 

class DataMessage2 : public DataMessage, public IDataLengthInfo { 
    Q_OBJECT 
    Q_INTERFACES(IDataLengthInfo) 
    // other fields 
    int dataLength() const; 
}; 

그리고 processDataMessages라는 클래스 기능 :

void MyClass::processDataMessages(DataMessage *msg) { 
    // Previous to this function being called, concrete `DataMessage` 
    // instances are created and passed by pointer into this function 

    // Determine the data in the message 
    IDataLengthInfo *dl = qobject_cast<IDataLengthInfo*>(msg); 

    if (dl) { 
     qDebug() << "Got a message with IDataLengthInfo"; 
    } 

    ITimeStampInfo *ts = qobject_cast<ITimeStampInfo*>(msg); 

    if (ts) { 
     qDebug() << "Got a message with ITimeStampInfo"; 
    } 

    // etc 
} 

processDataMessagesslot에 호출되는 전구체로서

, 나는 다음과 같은 클래스 및 "인터페이스"를 가지고 있다고 할 수 있습니다. 정상 작동 중에는이 기능이 완벽하게 작동하며 포인터가 정확할 때 qDebug() 문이 예상대로 실행됩니다. 예를 들어 디버거에서 포인터 유형을 검사하면

과 같은 유형이됩니다. 비동기 적으로 잠재적으로, 할 일이 조금있을 수 있습니다. 내가 슬롯 내에서 QtConcurrent::run를 사용하여이 기능을 실행하려고하면 다음과 같이

void MyClass::dataReceived(DataMessage *msg) { 
    // this->processDataMessages(msg); 
    QtConcurrent::run(this, &MyClass::processDataMessages, msg); 
} 

을 지금은 processDataMessages 기능의 첫 번째 qobject_cast 라인에서 휴식 할 때, 나는 msg 포인터 타입 인 것을 알 수 있습니다 DataMessage하지 DataMessage1 또는 DataMessage2 유형 중 하나입니다.

QtConcurrent::run의 작동 중에 뭔가가 손실되어 버렸습니다. 알고 보니 있도록

답변

0

좋아, 다음 코드는 작동합니다

QFuture<void> f = QtConcurrent::run(this, &MyClass::processDataMessages, msg); 
// Wait for the function to finish 
f.waitForFinished(); 

정말 반환 값의 원래하지만, 뭔가에 대한 서로 다른 상태를 유지 할 수있다 보이지 않는다?

+0

'msg'는'dataReceived'를 호출하는 함수에서 소멸 될 것으로 예상됩니다. 'waitForFinished'를 사용하여 주 스레드를 차단하면 비동기 동작을 이용하지 않게됩니다. – m7913d

+0

좋은 점은, 실제로'waitForFinished'가 메인 스레드를 막을 것이라고 생각하지 않았습니다. 음 ... – weblar83