2013-03-16 3 views
13

C++ 11vettore di std :: thread

Sto cercando di fare un vector di std::thread s. La combinazione dei seguenti tre punti dice che posso.

1.) Secondo http://en.cppreference.com/w/cpp/thread/thread/thread, thread 's costruttore di default crea un

thread object which does not represent a thread.

2.) Secondo http://en.cppreference.com/w/cpp/thread/thread/operator%3D, thread' s operator=

Assigns the state of [the parameter, which is a thread rvalue reference] to [the calling thread] using move semantics.

3.) Secondo http://en.cppreference.com/w/cpp/container/vector/vector, passando solo una variabile di tipo di dimensione per un costruttore di vettori costruirà ct

the container with [the specified number of] value-initialized (default constructed, for classes) instances of T. No copies are made.

Così, ho fatto questo:

#include <iostream> 
#include <thread> 
#include <vector> 

void foo() 
{ 
    std::cout << "Hello\n"; 
    return; 
} 

int main() 
{ 
    std::vector<std::thread> vecThread(1); 
    vecThread.at(0) = std::thread(foo); 
    vecThread.at(0).join(); 
    return 0; 
} 

Questo viene eseguito come previsto in VC11 e g++ 4.8.0 (online compiler here) come si vede nella seguente:

Console in uscita:

Hello 

Poi ho provato in clang 3.2, commutando il menu compilatore sulla stessa pagina Web, che assicura:

stderr: 
pure virtual method called 
terminate called without an active exception 

Quando un thread oggetto che rappresenta un filo esce dall'area di validità prima di essere join() ed o detach() ed, il programma sarà costretto a terminare. Ho join() ed vecThread.at(0), quindi l'unica cosa rimasta in questione è il filo temporanea

std::thread(foo);

nell'assegnazione

vecThread.at(0) = std::thread(foo);

.

Tuttavia, in base al riferimento Web, i thread possono essere assegnati solo spostando un riferimento di valore di thread. Non riesco a pensare a un modo per join() o detach() un oggetto thread temporaneo.

Quindi se l'output di clang è corretto, qual è l'utilizzo dioperator=? O questo è un bug del clang?

In g ++ 4.8.0, cambiando la linea

vecThread.at(0) = std::thread(foo)

a

vecThread.at(0) = std::thread{foo}

(sostituendo parentesi con graffe) dà ancora l'atteso Hello uscita.

Tuttavia, cambiando la linea per vecThread.at(0) = {foo} rende lamentano:

g ++ 4.8.0 di denuncia in parentesi:

error: converting to 'std::thread' from initializer list would use explicit constructor 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(); _Args = {}]' vecThread.at(0) = {foo};

che è troppo avanzato non so cosa significa.

Fare lo stesso cambiamento di clang dà l'ancor più avanzata: denuncia

clangore 3.2 di parentesi graffe su:

error: no viable overloaded '=' 
vecThread.at(0) = {foo}; 
... 
note: candidate function not viable: cannot convert initializer list 
argument to 'const std::thread' 
thread& operator=(const thread&) = delete; 
... 
note: candidate function not viable: cannot convert initializer list 
argument to 'std::thread' 
thread& operator=(thread&& __t) noexcept 

e non so che cosa significa neanche.

non posso usare VC11 per corroborare quanto sopra

vecThread.at(0) = {foo}

problemi perché VC11, come del compilatore CTP novembre 2012, non supporta la sintassi di inizializzazione uniforme sulla libreria standard.

+0

Hai compilato con '-pthread'? Il codice sembra buono, anche se un po 'prolisso. –

+0

Vuoi dire che dovrei aggiungere '-pthread' al campo di testo degli argomenti' compiler/interpreter' del compilatore online? L'ho aggiunto agli argomenti originali del compilatore/interprete del campo di testo della pagina web, rendendolo '-std = C++ 11 -Wall -W -pedantic -O2 -pthread' su clang, ma ho ottenuto gli stessi risultati con il' terminate' chiamato . – CodeBricks

+0

Bene, [questo codice] (http://ideone.com/4B2Elt) funziona per me quando compilato con '-std = C++ 0x -pthread' ... –

risposta

7

Il tuo primo esempio è corretto. Lanciare un'eccezione è un noto bug, quando si usa clang con libstdC++. Per risolverlo, è necessario installare libC++ (versione llvm della libreria C++). Vedere un esempio di compilazione con libC++ sotto

#include <thread> 

int main() 
{ 
    std::thread t([]() {}); 
    t.join(); 
    return 0; 
} 

$ clang++ -std=c++11 -stdlib=libc++ main.cpp -o main -lc++ -lsupc++ -lpthread

P.S. Vedi here, perché è richiesta anche la bandiera -lsupc++.