2016-08-07 3 views
1

Ich mag würde wissen, ob der folgende Code ist thread-safeThread-Sicherheit von innen Lambda mit unique_ptr wenn neuen Thread zu schaffen

void use_value(int i, unique_ptr<vector<int>> v); 
for (int i = 0; i < 10; i++){ 
    unique_ptr<vector<int>> ptr = make_unique<vector<int>>(10); 
    // ... 
    // Here, the vector pointed to by ptr will be filled with specific values for each thread. 
    // .... 
    thread(
     [i, &ptr](){ 
      use_value(i, move(ptr)); 
     } 
    ); 
} 

Danke

+0

Vielleicht ist dies nicht Ihr richtiger Code, aber dieses Beispielprogramm wird nach der ersten Iteration der Schleife beendet, da der 'std :: thread' [zerstört wird, während er noch in einem verknüpfbaren Zustand ist] (http: // en. cppreference.com/w/cpp/thread/thread/~thread). – Oktalist

+0

@Oktalist Sie haben Recht, es ist nicht der echte Code; aber ich habe mich für den Punkt interessiert. Du meinst den neu erstellten Thread wegen RAII? –

+0

'std :: thread' ist kein Thread, es verwaltet einen Thread. 'thread ([i, & ptr]() {use_value (i, move (ptr));});' erstellt einen temporären 'std :: thread', der nach dem letzten'; 'sofort zerstört wird. Das Zerstören eines initialisierten 'std :: thread' ohne ersten Aufruf von' join() 'oder' detach() 'führt zu einem vorzeitigen Programmende. Sie müssen den "std :: thread" irgendwo anders verschieben (oder konstruieren), damit er nicht sofort zerstört wird, was Ihr echter Code vermutlich bereits tut. – Oktalist

Antwort

3

Es ist nicht definiertes Verhalten. Sie wissen nicht, wann der Lambda-Körper aufgerufen wird. So dass ptr Sie durch Verweis erfassen kann sehr gut außerhalb des Geltungsbereichs bis dahin sein, die Ressource zerstört, und Sie sind mit einem baumelnden Verweis verlassen.

Sie sollten "move-capture" die ptr (oder besser noch, nur die vector) in das Lambda, wenn Sie Zugriff auf C++ 14 haben. Wenn Sie den Vektor verschieben (oder kopieren), ist Ihr Code threadsicher.

+0

Wird es nicht erstellt, wenn der Konstruktor 'thread' aufgerufen wird? –

+0

Nur ein Nit: das ist ungefähr Lebenszeit, nicht Umfang. – hvd

+0

@AhmadSiavashi, nur die Referenz wird bei der Lambda-Erstellung erfasst. Der Körper kann jederzeit aufgerufen werden, wenn 'std :: thread' involviert ist. – StoryTeller

Verwandte Themen