Frage

Also arbeite ich an einem Programm, dass Prozesse Videos in Echtzeit-und ich habe einige Schwierigkeiten mit Gewinde "blockieren" sich gegenseitig.

Mein system ist ziemlich viel, wie folgt eingerichtet:

         DataSourceThread
             /      \
            /        \
           /          \
     Receiver       Receiver
         /              \
        /                \ 
       /                  \
 Processor1            Processor2

(Alle diese Klassen erweitern die QThread.)

So DataSourceThread holt der Rahmen aus Videostreams und sendet ein signal, den Rahmen an den Empfänger. Connection type:Qt::DirectConnection

Der Empfänger grundsätzlich erhalten die Rahmen gesendet von DataSourceThread, und wenn der Prozessor erfolgt die Verarbeitung der vorige Bild, es wird emittieren ein signal mit dem Rahmen auf den Prozessor. Connection type:Qt::QueuedConnection. Wenn der Prozessor nicht getan Verarbeitung der vorigen Bild, wird es einfach zurück, ohne ein signal ausstrahlt (überspringen von frames).

Um zu testen, ob dies funktioniert, habe ich nichts anderes getan haben Processor1 nur eine Meldung ausgeben, wenn es erhält einen Rahmen und Processor2 tut QThread::sleep(3); und eine Meldung ausgeben.

(Der Empfänger wird auch eine Tiefe Kopie des Rahmens, bevor diese an die Prozessoren.)

Erwartetes Ergebnis:

Processor1 sollte ständig Nachrichten drucken.Processor2 sollte drucken einer Nachricht alle 3 Sekunden.

Das problem:

Beide Prozessoren drucken Ihre Botschaften in der gleichen Zeit (alle 3 Sekunden).Processor1 wartet, bis Processor2 erfolgt vor dem drucken Ihre Nachricht.So die Ausgabe ist ziemlich viel, wie dieses:

"Message from processor1"
"Message from processor2"
"Message from processor1"
"Message from processor2"
"Message from processor1"
"Message from processor2"

und so weiter.

Ich bin running out of Ideen hier, also jede Hilfe würde sehr geschätzt werden!

EDIT: Hier sind einige code:

main.cpp:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    DataSourceThread dataSourceThread;
    dataSourceThread.start();

    GUIThread *guiProcessor = new GUIThread();
    FrameReceiver *guiReceiver = new FrameReceiver(guiProcessor, 0);

    QObject::connect(
        &dataSourceThread, SIGNAL(frameReceived(Frame*)),
        guiReceiver, SLOT(receive(Frame*)),
        Qt::DirectConnection
    );

    DetectorThread *detectorProcessor = new DetectorThread();
    FrameReceiver *detectorReceiver = new FrameReceiver(detectorProcessor, 0);

    QObject::connect(
        &dataSourceThread, SIGNAL(frameReceived(Frame*)),
        detectorReceiver, SLOT(receive(Frame*)),
        Qt::DirectConnection
    );

    return app.exec();
}  

Von DataSourceThread.cpp:

void DataSourceThread::run()
{
    ... stuff ...

    while (true) {
        image = cvQueryFrame(capture);

        if (!image) { 
            qDebug() << QString("Could not capture frame"); 
            continue;
        }

        cvReleaseImage(&temp_image);
        temp_image = cvCreateImage(cvSize(640, 480), image->depth, 3);

        cvResize(image, temp_image, 1);

        frame->lock();
        frame->setImage(temp_image);
        frame->unlock();

        emit frameReceived(frame);

        msleep(1); 
    }
} 

FrameReceiver.cpp:

FrameReceiver::FrameReceiver(FrameProcessor* processor, QObject *parent) : QThread(parent) {
    m_ready = true;

    m_processor = processor;
    m_processor->start();

    QObject::connect(
        (QObject*)this, SIGNAL(frameReceived(Frame*)),
        m_processor, SLOT(receive(Frame*)), 
        Qt::QueuedConnection
    );

    QObject::connect(
        m_processor, SIGNAL(ready()),
        (QObject*)this, SLOT(processCompleted()),
        Qt::DirectConnection
    ); }

void FrameReceiver::processCompleted() {
    m_ready = true; }

void FrameReceiver::receive(Frame *frame) {
    if (m_ready == true) {
        m_ready = false;
        frame->lock();
        Frame *f = new Frame(*frame);
        frame->unlock();
        emit frameReceived(f);
    } else {
        // SKIPPED THIS FRAME
    }
}

GUIThread.cpp:(Processor1)

GUIThread::GUIThread(QObject *parent) : FrameProcessor(parent)
{
    m_frame = new Frame();
}

void GUIThread::setFrame(Frame *frame)
{ 
    qDebug() << QString("Guithread received frame");
}    

FrameProcessor.cpp

// (The processors extend this class)
void FrameProcessor::receive(Frame *frame)
 {
     setFrame(frame);
     delete frame;
     emit ready();
 }

DetectorThread (Processor2) macht das gleiche wie guithread, aber mit einem 3 sec schlafen in setFrame.

War es hilfreich?

Lösung

Ich denke, ein Teil des Problems ist, dass alle Ihre QObjects sind im Besitz der main application thread.Dies bedeutet, dass Sie alle teilen ein one-event-Schleife, die für die Bereitstellung asynchroner Signale, effektiv serialisieren Sie Ihre gesamte Prozesskette.

Ich denke, der richtige Weg, um dies einzurichten wäre so etwas wie:

GUIProcessor *guiProcessor = new GUIProcessor();
QThread guiProcessorThread;
guiProcessor.moveToThread(&guiProcessorThread);

FrameReceiver *guiReceiver = new FrameReceiver(guiProcessor, 0);
QThread guiReceiverThread;
guiReceiver.moveToThread(&guiReceiverThread);

guiProcessorThread.start();
guiReceiverThread.start();

Wenn Sie es so machen, würde ich vorschlagen, nicht mit DirectConnection zwischen den Fäden, sondern BlockingQueuedConnection wenn Sie sicherstellen möchten, dass das aktuelle Bild verarbeitet wird, bevor Sie erfassen die nächste.

Siehe dies: http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/

Und dieses: http://labs.qt.nokia.com/2006/12/04/threading-without-the-headache/

Hoffe, das hilft!

EDIT:Um klar zu sein, mit meinem Vorschlag, Ihre Klassen Erben würde QObject anstelle von QThread.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top