2013-03-16 43 views
13

C++ 11vector của std :: Các luồng

tôi đang cố gắng để thực hiện một vector của std::thread s. Sự kết hợp của ba điểm sau đây nói rằng tôi có thể.

1.) Theo http://en.cppreference.com/w/cpp/thread/thread/thread, thread 's constructor mặc định tạo ra một

thread object which does not represent a thread.

2.) Theo 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.) Theo http://en.cppreference.com/w/cpp/container/vector/vector, chuyển qua chỉ một biến loại kích thước cho một hàm tạo vector sẽ constru ct

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

Vì vậy, tôi đã làm điều này:

#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; 
} 

này chạy như mong đợi trong VC11 và g++ 4.8.0 (online compiler here) như đã thấy trong những điều sau đây:

điều khiển Output:

Hello 

Sau đó, tôi đã thử nó trong vang 3.2 bằng cách chuyển đổi menu trình biên dịch trên cùng một trang web, mang đến cho:

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

Khi một sợi đối tượng đại diện cho một thread-đi ra khỏi phạm vi trước khi join() ed hoặc detach() ed, chương trình sẽ buộc phải chấm dứt. Tôi có join() ed vecThread.at(0), do đó, điều duy nhất còn lại trong câu hỏi là thread tạm thời

std::thread(foo);

trong việc bố trí

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

.

Tuy nhiên, theo tham chiếu web, chủ đề chỉ có thể được chỉ định bằng cách di chuyển tham chiếu rvalue chuỗi. Tôi không thể nghĩ ra bất kỳ cách nào để join() hoặc detach() một đối tượng chuỗi tạm thời.

Vì vậy, nếu đầu ra của tiếng kêu là chính xác, thì việc sử dụng thread của operator= là gì? Hay đây là một lỗi trình biên dịch clang?

Trong g ++ 4.8.0, thay đổi dòng

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

để

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

(thay thế ngoặc với niềng răng) vẫn đưa ra dự kiến ​​Hello đầu ra.

Tuy nhiên, thay đổi dòng để vecThread.at(0) = {foo} làm cho nó phàn nàn:

g ++ khiếu nại 4.8.0 về niềng răng:

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};

mà là quá cao-Tôi không biết ý nghĩa của nó.

Làm cùng một thay đổi trong vang đưa ra thậm chí còn cao cấp hơn: khiếu nại

kêu vang 3.2 về niềng răng:

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 

và tôi không biết điều đó có nghĩa là một trong hai.

tôi không thể sử dụng VC11 để chứng thực trên

vecThread.at(0) = {foo}

vấn đề vì VC11, tính đến trình biên dịch CTP tháng 11 năm 2012, không hỗ trợ cú pháp khởi tạo thống nhất về bộ thư viện chuẩn.

+0

Bạn đã biên dịch bằng '-pthread' chưa? Mã có vẻ tốt, mặc dù một chút tiết. –

+0

Bạn có nghĩa là tôi nên thêm '-pthread' vào trường văn bản đối số' trình biên dịch/phiên dịch 'của trình biên dịch trực tuyến không? Tôi đã thêm nó vào các đối số biên dịch/phiên dịch gốc của trường văn bản, làm cho nó '-std = C++ 11 -Wall -W -pedantic -O2 –pthread' trên clang, nhưng có cùng kết quả với' terminate' được gọi . – CodeBricks

+0

Vâng, [mã này] (http://ideone.com/4B2Elt) hoạt động cho tôi khi được biên dịch với '-std = C++ 0x -pthread' ... –

Trả lời

7

Ví dụ đầu tiên của bạn là chính xác. Ném một ngoại lệ là bug, khi bạn sử dụng clang với libstdC++. Để giải quyết nó, bạn phải cài đặt libC++ (phiên bản llvm của thư viện C++). Xem ví dụ về biên soạn với libC++ bên dưới

#include <thread> 

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

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

T.B. Xem here, tại sao cờ cũng được yêu cầu -lsupc++.

Các vấn đề liên quan