2017-07-16 2 views
0

Ich habe einen Vektor von Zeichenfolgen, die eine gemeinsame Ressource ist.Umschalten der Ausführung zwischen 2 Threads in C++, wenn Threads eine Schleife zwischen Mutex sperren und entsperren

std::vector<std::string> vecstr; 

Habe 2 Fäden, die parallel laufen:

Thread1: Um Strings geteilt resourse einzufügen.

Thread2: Um die Größe der gemeinsamen Ressource zu berechnen.

std::mutex mt; 

void f1() 
{ 
    mt.lock(); 
    while(some_condition()) 
    { 
     std::string str = getStringFromSomewhere(); 
      vecstr.push_back(str); 

    } 

    mt.unlock(); 
} 

size_t f2() 
{ 
    mt.lock(); 
    while(string_sending_hasEnded()) 
    { 
     size_t size = vecstr.size(); 
    } 
    mt.unlock(); 
} 

int main() 
{ 
std::thread t1(f1); 
std::thread t2(f2); 
t1.join(); 
t2.join(); 

} 

Meine Frage ist: wenn der t1 Thread die vecstr gemeinsam genutzte Ressource Mutex für die gesamte while-Schleife Dauer gesperrt hält wird, wie die T2 habhaft der gemeinsam genutzten Ressource vecstr zu berechnen es Größe ist? Schaltet die Ausführung zwischen den 2 Threads um oder hängt davon ab, wer Mutex 1st ergreift. Wenn T1 also Mutex hat, wird es erst nach dem Ende der While-Schleife freigegeben. Ist das wahr ? Oder die Ausführung wechselt zwischen den 2 Threads.

Wenn einer der Faden wird um die Ausführung von nicht ermöglicht anderen Thread zu überfallen zu schalt dazwischen dann wie gehen i ein solches Szenario mit while/for-Schleifen in jedem Thread aber beide Fäden muss kontinuierlich ausgeführt werden? Wobei ich beide Threads an weiterschalten möchte. Soll ich innerhalb der While-Schleife sperren und entsperren, so dass jede Iteration Mutex gesperrt hat & entsperrt?

+0

Bedenken Sie, dass die berechnete Größe irgendwie irrelevant ist, d. H. Sie haben nur einen Hinweis darauf, wie groß die Größe der freigegebenen Ressource in der Vergangenheit war. Es ist nicht klar, wie Sie diese Informationen verwenden möchten. – juanchopanza

+0

Da dies die Version mit den Antworten ist, denke ich, sollten wir die andere Version als ein Duplikat davon markieren, anstatt umgekehrt. (** done **) – Galik

+0

was soll dein 'f2()' thread machen? Wie es geschrieben steht, sieht es so aus, als ob es entweder sofort stirbt, ohne überhaupt etwas zu tun (wenn "string sending" nicht "beendet" ist), oder es wird für immer eine Schleife durchlaufen, ohne etwas Nützliches zu tun (wenn "string sending" _has_ "beendet wurde) "). –

Antwort

1

Also, wenn T1 halten Mutex bekam dann wird es sie erst frei, nachdem while-Schleife endet? Ist das wahr ?

Ja, das stimmt.

Beide Threads sperren den mt Mutex über die gesamte Zeit, in der diese Schleifen ausgeführt werden.


Was your comment

Wenn das der Fall ist, wie kann ich ein solches Szenario umgehen? Wo ich möchte, dass beide Threads ihre Ausführung wechseln. Soll ich in der while-Schleife sperren und entsperren, so dass jede Iteration Mutex & entriegelten

Ja verwenden mehr feinkörniges Verriegelungs gesperrt hat, nur für die Operationen, die Änderung/des Vektors zuzugreifen:

std::mutex mt; 

void f1() { 
    while(some_condition()) { 
     std::string str = getStringFromSomewhere(); 
     { std::unique_lock(mt); // -+ 
      vecstr.push_back(str); // | locked 
     }       // -+ 
    } 
} 

size_t f2() { 
    while(string_sending_hasEnded()) { 
     size_t size = 0; 
     { std::unique_lock(mt); // -+ 
      size = vecstr.size(); // | locked 
     }       // -+ 
    } 
} 

Ich empfehle auch sehr, einen Lock-Guard zu verwenden (wie in meinem Beispiel std::unique_lock), anstatt lock()unock() manuell zu verwenden. So ist es sicher, dass der Mutex entsperrt wird, z. im Falle von Ausnahmen ausgelöst.

+0

Wenn das der Fall ist, wie gehe ich mit einem solchen Szenario um? Wo ich möchte, dass beide Threads ihre Ausführung wechseln. Soll ich innerhalb der While-Schleife sperren und entsperren, sodass bei jeder Iteration Mutex gesperrt und entsperrt ist? – codeLover

+0

@codeLover Verwenden Sie eine feinkörnigere Verriegelung, z. Sperren Sie nur, wenn Sie etwas im Vektor ändern. Verwenden Sie 'std :: lock_guard' mit der Operation' push_back() 'und greifen Sie auf' size() 'zu. – user0042

+0

Danke. Wird das Locking in der von dir gezeigten Art und Weise stattfinden, wird die Ausführung zwischen den 2 Threads umgeschaltet. – codeLover

2

Sie haben es. Wenn Sie Mutexe im wirklichen Leben erfolgreich einsetzen wollen, werden Sie einen Mutex nur für die kürzest mögliche Zeit behalten. Zum Beispiel nur um die Aufrufe push_back() und size() herum.

Aber wirklich, was Sie zuerst tun müssen, ist herauszufinden, was Ihr Programm tun soll, und dann Mutexe verwenden, um sicherzustellen, dass dies zu erreichen. Im Moment weiß ich, dass Sie einige Threads ausführen möchten, aber das ist nicht das, was Sie erreichen möchten.

Verwandte Themen