2014-10-21 9 views
8

Könnte mir jemand erklären, warum bitte beide Threads in diesem Programm sind gesperrt (wenn mit Visual Studio 2012/2013 mit den verschifft Compiler kompiliert), bis beide std::call_once Anrufe ausgeführt werden? Ein weiterer Visual Studio-Fehler (vorausgesetzt, er verhält sich wie erwartet, wenn er mit GCC kompiliert wird)? Kann mir jemand einen Workaround einfallen lassen? Stell dir all den Schmerz vor, den ich durchgemacht habe, um das Problem zu verringern und bitte, sei barmherzig.Concurrent std :: call_once ruft

#include <chrono> 
#include <iostream> 
#include <mutex> 
#include <thread> 

namespace 
{ 
    std::once_flag did_nothing; 

    void do_nothing() 
    { } 

    void sleep_shorter_and_do_nothing_once() 
    { 
     std::this_thread::sleep_for(std::chrono::seconds(3)); 
     std::cout << "1\n"; 
     std::call_once(did_nothing, do_nothing); 
     std::cout << "2\n"; 
    } 

    std::once_flag sleeped_longer; 

    void sleep_longer() 
    { 
     std::this_thread::sleep_for(std::chrono::seconds(10)); 
    } 

    void sleep_longer_once() 
    { 
     std::cout << "3\n"; 
     std::call_once(sleeped_longer, sleep_longer); 
     std::cout << "4\n"; 
    } 
} 

int main() 
{ 
    std::thread t1(sleep_shorter_and_do_nothing_once); 
    std::thread t2(sleep_longer_once); 
    t1.join(); 
    t2.join(); 
    return 0; 
} 

Um dies näher auszuführen, verhält es sich wie bei der Verwendung von GCC kompiliert erwartet:

  • prints "3",
  • wartet 3 Sekunden
  • druckt "1",
  • sofort druckt "2"
  • wartet weitere 6-7 Sekunden,
  • und druckt "4".

Bei Verwendung der mit Visual Studio 2012/2013 ausgeliefert Compiler kompiliert wird, verhält es sich wie folgt aus:

  • prints "3",
  • wartet 3 Sekunden
  • druckt "1" ist,
  • wartet weitere 6-7 Sekunden,
  • und nur dann druckt sofort "2" und "4".

Offensichtlich ist es ein Fehlverhalten. Oder nicht?

UPDATE: Ich kann dies nicht als Visual Studio Bug einreichen, weil mein Arbeitskonto aus irgendeinem Grund "nicht autorisiert ist, Feedback für diese Verbindung zu senden", was auch immer das bedeutet. Ich habe eine Antwort von dem Microsoft STL Betreuer bekommt sagen, dass er hoffentlich das Problem zu einem bestimmten Zeitpunkt in der Zukunft untersuchen werde.

Antwort

2

Ich habe eine Antwort von der STL Betreuers bei Microsoft bekam sagen, die in Visual Studio Fest Bug 2015

+0

wenn es sich um eine öffentliche Antwort Link in Ihrer Antwort – UmNyobe

+0

@UmNyobe ist traurig, dass ich bin, ist es eine war Email. Es war sowieso lange her. Und ich sollte eindeutig nicht beheben Grammatik/Formatierung in meinem älteren Fragen, wie es aus irgendeinem Grund viel neuen Kommentaren angespornt! –

+1

in VS2015 Erwähnt Release Notes unter DevDiv # 1092852: https://blogs.msdn.microsoft.com/vcblog/2015/07/14/stl-fixes-in-vs-2015-part-2/ –

0

Er bevorzugt ein schlechtes Benehmen zu sein.
„Der Abschluss einer wirksamen Verbindung auf einem Objekt zu once_flag call_once synchronisiert sich mit allen nachfolgenden Anrufen an die gleiche once_flag Objekt call_once.“ (N3242, 30.4.4.2-Klausel-3).