2017-01-04 3 views
1

ich eine Anwendung mit 2 QThreads haben zu erwerben versuchen, die weiter unten in der Pseudo-Code wie es sich verhalten (die Semaphore vom Typ QSemaphore):Mutex Unlock-Fehler, wenn ein QSemaphore

Thread1 { 
    print("about to wait on semaphore 1"); 
    sem1.acquire(1); 
    print("finished waiting on semaphore 1"); 
    sem2.release(1); 
} 

Thread2 { 
    print("signaling semaphore 1"); 
    sem1.release(1); 
    print("about to wait on semaphore 2"); 
    sem2.acquire(1); 
} 

Das Problem ist, dass das erste Gewinde nicht aufwacht, wenn der erste Semaphore signalisiert wird, dh die Anwendung die folgende Ausgabe erzeugt:

about to wait on semaphore 1 
signaling semaphore 1 
about to wait on semaphore 2 

Und das ist es. Der erste Thread wacht nicht mehr auf.

Jetzt wechsle ich den ersten Thread folgendes zu tun:

Thread1 { 
    print("about to wait on semaphore 1"); 
    while (!sem1.tryAcquire(1, 200)); 
    print("finished waiting on semaphore 1"); 
    sem2.release(1); 
} 

In diesem Fall ist der erste Thread schläft für höchstens 200 ms, bevor er wieder die Semaphore zu erwerben versucht. Jetzt bekomme ich folgende Fehlermeldung:

QWaitCondition::wait(): mutex unlock failure: Invalid argument 

Keine andere mutexes oder andere Synchronisations Primitiven von der Anwendung verwendet werden. Was könnte das Problem sein?

aktualisieren:

Ich habe die Semaphore entfernt und ersetzt die jeweils mit einem QWaitCondition und einem QMutex und jetzt funktioniert es ganz gut. Ich habe keine weiteren Änderungen vorgenommen und weiß immer noch nicht, warum die Version mit Semaphoren falsch war. Sie wurden beide auf 0 initialisiert.

Antwort

0

Wahrscheinlich machen Sie etwas falsch woanders (z. B. Semaphor Initialisierungscode).


Im folgenden Beispiel wird kompiliert und ausgeführt (gcc).

threads.h:

#pragma once 

#include <QThread> 

class Thread1 : public QThread 
{ 
protected: 
    virtual void run(); 
}; 

class Thread2 : public QThread 
{ 
protected: 
    virtual void run(); 
}; 

threads.cpp:

#include "threads.h" 

#include <QSemaphore> 
#include <iostream> 

namespace 
{ 
QSemaphore sem1, sem2; 
} 

void Thread1::run() 
{ 
    std::cout << "about to wait on semaphore 1\n"; 
    sem1.acquire(1); 
    //while (!sem1.tryAcquire(1, 200));  //works too 
    std::cout << "finished waiting on semaphore 1\n"; 
    sem2.release(1); 
} 

void Thread2::run() 
{ 
    std::cout << "signaling semaphore 1\n"; 
    sem1.release(1); 
    std::cout << "about to wait on semaphore 2\n"; 
    sem2.acquire(1); 
} 

main.cpp:

#include "threads.h" 
#include <iostream> 

int main(int argc, char *argv[]) 
{ 
    Thread1 t1; 
    Thread2 t2; 
    t1.start(); 
    t2.start(); 
    t1.wait(); 
    t2.wait(); 
    std::cout << "Success\n"; 
} 

möglich Ausgabe:

signaling semaphore 1 
about to wait on semaphore 2 
about to wait on semaphore 1 
finished waiting on semaphore 1 
Success 
+1

Hinweis: Ihr Beispiel muss nicht '' noch mehr Dateien verwenden. Verwenden Sie 'qDebug() <<" Success ";' und verwenden Sie nur eine einzelne '#include ' in 'main.cpp'. –

+0

@Kuba Ober threads.h gibt es wegen Moc, threads.cpp gibt es für die Lokalisierung von Semaphoren in einer separaten Übersetzungseinheit. Und ich bevorzuge die Standardbibliothek der Sprache gegenüber der Implementierung von Qt (Geschmackssache) :-) – AMA

+0

Ich habe die Semaphore entfernt und jeweils durch ein QWaitCondition und ein QMutex ersetzt und jetzt funktioniert es ganz gut. Ich habe keine weiteren Änderungen vorgenommen und weiß immer noch nicht, warum die Version mit Semaphoren falsch war. Sie wurden beide auf 0 initialisiert. – user1576490