2013-09-06 38 views
7

Tôi đọc rất nhiều bài đăng ở đây với câu hỏi nếu vùng chứa tiêu chuẩn cho C++ (như "danh sách" hoặc "bản đồ" là an toàn và tất cả đều nói rằng đó không phải là nói chung. đọc nên OK, nhưng song song viết hoặc song song đọc và viết có thể gây ra vấn đềAn toàn chủ đề của C++ std Vùng chứa

Bây giờ tôi phát hiện ra rằng ở www.cplusplus.com rằng việc truy cập hoặc sửa đổi danh sách trong hầu hết các hoạt động an toàn

Một số ví dụ:..

map::find

Vùng chứa được truy cập (không phải là phiên bản const cũng như không phải sửa đổi vùng chứa). Không có giá trị được ánh xạ nào được truy cập: đồng thời truy cập hoặc sửa đổi các phần tử là an toàn.

map::insert

Thùng chứa được sửa đổi. Đồng thời truy cập các thành phần hiện có là an toàn, mặc dù các dải lặp trong vùng chứa không phải là.

Tôi có hiểu nhầm cplusplus.com hoặc có bất kỳ điều gì khác mà tôi phải biết về an toàn luồng trong các thùng chứa std hay không.

Cảm ơn trước!

PS: Tôi đang yêu cầu cho C++ 03 và không cho C++ 11

+4

Về mặt tài nguyên, có vẻ như [cppreference] (http://en.cppreference.com/w/cpp) đáng tin cậy hơn; bạn có thể muốn bắt đầu sử dụng nó thay vì cplusplus.com. –

+0

@MatthieuM. [cppreference vẫn đang thảo luận] (http://en.cppreference.com/w/Talk:Main_Page#Thread_safety) cách diễn tả chính xác '23.2.2 [container.requirements.dataraces]/1' và' 17.6.5.9 [res .on.data.races] ' – Cubbi

+0

@Cubbi: chứng minh rằng họ quan tâm đến nó :) –

Trả lời

5

Âm thanh phù hợp.

Lưu ý rằng việc truy cập các giá trị trong phạm vi map từ nhiều luồng, nếu bạn sửa đổi giá trị thực, cũng sẽ cần được bảo vệ. Nếu bạn BIẾT rằng hai chủ đề cập nhật các mục KHÁC (tôi không có nghĩa là chèn/xóa), thì nó an toàn.

+0

Nhưng điều gì xảy ra với chính vùng chứa (không chỉ dữ liệu được lưu trữ trong đó)? Điều gì sẽ xảy ra nếu hai chủ đề cố gắng chèn các mục mới khác nhau đồng thời? – mrwerner

+1

@mrwerner Đó sẽ là một cuộc đua dữ liệu (nghĩa là xấu), vì cả hai cố gắng sửa đổi cùng một đối tượng (nghĩa là vùng chứa). –

+1

@merwerner: một bản đồ là một loại cây nhị phân. Nếu hai chủ đề đang cố gắng sửa đổi cây (ví dụ: trả lại nó), bạn sẽ kết thúc bằng một MESS! –

3

Trước khi C++ 11, không có khái niệm "chủ đề" trong tiêu chuẩn. Vì vậy, câu hỏi liệu một container là thread-safe là vô nghĩa trong ngữ cảnh của C++ 03.

+7

Đây là nhận xét chứ không phải là câu trả lời. –

11

Đọc song song phải OK, nhưng viết song song hoặc đọc và ghi song song có thể gây ra sự cố.

Đúng vậy. Đó là sự bảo đảm được cung cấp nói chung cho truy cập không đồng bộ với các đối tượng trong C++. Những "vấn đề" như vậy được chính thức gọi là chủng tộc dữ liệu.

Bây giờ tôi phát hiện ra rằng tại www.cplusplus.com rằng việc truy cập hoặc sửa đổi danh sách trong hầu hết các thao tác là an toàn.

Không, bộ chứa không cung cấp nhiều hơn bảo lãnh cơ bản cho đồng thời lần đọc. Sẽ có một cuộc đua dữ liệu nếu một luồng truy cập vào nó trong khi một luồng khác sửa đổi nó. Tuy nhiên, với một số thùng chứa, đôi khi an toàn để truy cập vào các yếu tố của vùng chứa trong khi chính vùng chứa được sửa đổi.

Ví dụ đầu tiên là nói rằng find không không sửa đổi các yếu tố container hoặc truy cập giá trị (chỉ có phím), như vậy là an toàn nếu đề khác đang truy cập vào nó, hoặc sửa đổi các giá trị (khác nhau) mà không sửa đổi lại hộp đựng . Ví dụ thứ hai là nói rằng bạn có thể truy cập một phần tử hiện có một cách an toàn (sử dụng một tham chiếu hoặc vòng lặp tới phần tử đó), vì việc chèn một phần tử sẽ không can thiệp vào phần tử hiện có.

tôi yêu cầu cho C++ và không cho 11

C++

Những ngày này, C++ C++ 11. Nếu bạn đang hỏi về các phiên bản lịch sử của ngôn ngữ, họ không có gì để nói về chủ đề, do đó, câu hỏi không phải là câu trả lời nói chung, chỉ cho một thực hiện cụ thể và khung chủ đề.

0

Như Marcin đã chỉ ra, C++ 03 không có khái niệm về chủ đề; do đó, bạn không thể giả sử bất kỳ hoạt động an toàn luồng nào ngay cả đối với việc đọc đồng thời trong hai luồng sau khi viết xong hoàn toàn.

Hãy suy nghĩ về trường hợp này: Tại t = 0, bạn tạo chuỗi, hãy gọi A Tại t = 10 giây, chủ đề B (tồn tại trước khi chuỗi A được tạo) ghi vào vùng chứa. Tại t = 1 giờ, chủ đề A và B đều cố gắng đọc vùng chứa mà không cần đồng bộ hóa thông qua thư viện của bên thứ ba (ví dụ: pthread).

C++ 03 chỉ đảm bảo rằng chuỗi B sẽ thấy giá trị chính xác. Nhưng không có gì đảm bảo rằng luồng A sẽ thấy giá trị chính xác vì C++ 03 mong đợi mọi chương trình là một chuỗi đơn lẻ, và vì vậy đặc tả C++ 03 chỉ có thể đảm bảo chuỗi sự kiện hiển thị theo thứ tự được lập trình (như thể trong 1) thread).

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