2012-10-30 67 views
9

Dưới đây là kịch bản:C++ unordered_map STL, an toàn thread nơi mỗi thread truy cập duy nhất đó là phím đã gán riêng và có thể chỉnh sửa giá trị

1) sử dụng một unordered_map<int, vector<MyClass*>*> giả sử tôi thêm phím 1, 2, ... 8
2) tất cả các phím được đặt bằng vectơ khi khởi tạo chương trình và không có gì được thêm hoặc xóa
3) Tôi có 8 chuỗi, trong đó thread1 truy cập khóa [1], thread2 truy cập khóa [2], ... thread8 phím truy cập [8] (tức là số chỉ có thể truy cập số khóa đó và không có phím nào khác)

Thỉnh thoảng tôi gán lại giá trị vecto r * đến một bộ sưu tập phân bổ đống khác. (ví dụ: thread1 thực hiện key[1] = new vector<MyClass*>)

Tôi tin rằng đây sẽ là chủ đề an toàn, tôi có đúng không? Nếu không, tôi cho rằng tôi sẽ sử dụng concurrent_unordered_map.

cảm ơn.

+0

Tôi vừa phát hiện ra rằng '[container.requirements.dataraces]/1' cho phép điều này được thực hiện theo cách đẹp hơn tôi đã đề xuất trong câu trả lời ban đầu. Xin vui lòng xem qua. – Mankarse

Trả lời

11

Câu trả lời cho câu hỏi này có thể được tìm thấy trong [res.on.data.races]/3:

Một C++ thư viện tiêu chuẩn chức năng sẽ không trực tiếp hoặc gián tiếp thay đổi các đối tượng (1.10) thể truy cập bằng đề khác với thread hiện tại trừ các đối tượng được truy cập trực tiếp hoặc gián tiếp thông qua các đối số phi const của hàm, kể cả điều này.

Hơn nữa, [container.requirements.dataraces]/1 trạng thái:

Đối với mục đích tránh các cuộc đua dữ liệu ([res.on.data.races]), triển khai xem xét các chức năng sau đây để được const: begin, end, rbegin, rend, front, back, data , find, lower_bound, upper_bound, equal_range, at và, ngoại trừ liên kết hoặc không có thứ tự đồ đựng sơ cấp, operator[].

Kể từ unordered_map::operator[] là không const, nó là hợp pháp cho việc thực hiện để thay đổi unordered_map khi một cuộc gọi đến operator[] xảy ra. thay vào đó bạn nên sử dụng unordered_map::find, được yêu cầu một cách rõ ràng được đối xử như const, và do đó sẽ không thay đổi unordered_map:.

map.find(key)->second = new vector<MyClass*>; 

(Như một mặt lưu ý, thiết kế đề nghị của bạn trông giống như một công thức cho rò rỉ bộ nhớ Tại sao không làm cho nó là một unordered_map<int, std::unique_ptr<vector<MyClass*>>>, hoặc unordered_map<int,vector<MyClass*>>?)

+1

Tôi sẽ bỏ phiếu cho giải pháp thay thế thứ hai (không có điểm nào đặt véc tơ trên heap nói chung). –

+0

Cảm ơn bạn đã trả lời. Tôi sẽ sử dụng một concurrent_unordered_map và không đặt các vector trên heap (để đơn giản, mặc dù tôi đang quản lý nó correcly trong mã). – GreekFire