2012-07-24 33 views
5

Tôi đã suy nghĩ về việc viết một lớp container để kiểm soát truy cập vào một cấu trúc dữ liệu phức tạp sẽ sử dụng trong môi trường đa luồng.C++ constructors và concurrency

Và câu hỏi xảy ra với tôi:

Có bao giờ một tình huống mà nhà xây dựng C++ phải được thread-an toàn không?

Trả lời

2

Không có kinh nghiệm của tôi. Đó là mã mà gọi hàm tạo, ngầm hoặc cách khác, cần được tạo an toàn cho luồng nếu ứng dụng yêu cầu nó.

Lý do là chỉ có một luồng phải khởi tạo một đối tượng tại một thời điểm, vì vậy không cần đồng bộ hóa để bảo vệ đối tượng đang được khởi tạo trong chính constructor (nếu đối tượng không hoàn thành khởi tạo, không nên được chia sẻ giữa các luồng).

Một cách khác để xem xét vấn đề này là: Đối tượng được coi là không tồn tại một cách hợp lý cho đến khi các hàm tạo của chúng trả lại. Vì vậy, một chủ đề đó là trong quá trình tạo ra một đối tượng là chủ đề duy nhất mà "biết" về nó.

Tất nhiên, quy tắc đồng bộ hóa thích hợp áp dụng đối với bất kỳ tài nguyên chia sẻ các nhà xây dựng tự truy cập, nhưng áp dụng cho bất kỳ chức năng (Tôi đã gặp những người mà không nhận ra điều này, nhà thầu tin tưởng là đặc biệt và bằng cách nào đó cung cấp truy cập độc quyền tất cả tài nguyên).

+0

Điều này không hoàn toàn đúng. Có những mối quan tâm về thread-safe cho constructor khi bạn sử dụng mẫu thiết kế singleton. Và ngay bây giờ tôi đang tìm kiếm một giải pháp cho tình huống này. – PDuarte

3

Chắc chắn bạn có thể gọi cùng một hàm tạo từ nhiều hơn một luồng cùng một lúc. Nghĩa là, chúng phải an toàn chỉ, giống như bất kỳ chức năng nào khác. Nếu hàm tạo sẽ sửa đổi trạng thái chia sẻ, ví dụ, vùng chứa của bạn, thì bạn phải sử dụng đồng bộ hóa để đảm bảo rằng trạng thái được sửa đổi theo cách xác định. Bạn không thể xây dựng cùng một đối tượng trên nhiều luồng cùng một lúc, bởi vì mỗi đối tượng chỉ được xây dựng một lần, vì vậy không có cách nào để gọi hàm tạo trên cùng một đối tượng nhiều hơn một lần, ít hơn nhiều trên hai chủ đề khác nhau cùng một lúc.

+0

Trong c + + đối tượng tồn tại về mặt kỹ thuật cho đến khi hàm tạo hoàn thành, vì vậy nếu contructor không có tác dụng phụ bên ngoài đối tượng, thì các chủ đề khác có thể truy cập nó không? – ThomasMcLeod

+1

Nhưng có những cách mà bạn có thể kết thúc cố gắng để xây dựng hai đối tượng khác nhau trong cùng một không gian cùng một lúc ... vị trí mới đến với tâm trí. Trong khi bạn có thể không làm điều này cho mình. Điều này cũng có thể xảy ra nếu bạn đang đẩy lùi các mục nhập vào một vectơ. Điều này không thể xảy ra nếu bạn có đồng bộ hóa bảo vệ vị trí bộ nhớ của các đối tượng được tạo ra mặc dù - trong ví dụ này là một khóa trên vectơ. –

+0

@MichaelAnderson, tôi không theo ví dụ vector của bạn. – ThomasMcLeod

4

Nói chung, một hàm tạo không thể được gọi cho đối tượng cùng một đối tượng bởi hai luồng cùng một lúc. Tuy nhiên, cùng một hàm tạo có thể được gọi cho các đối tượng khác nhau cùng một lúc.

+0

Không đúng đối với mẫu đơn. – PDuarte

+0

@PDuarte với một singleton, vẫn chỉ có một nhà xây dựng được gọi là một lần. –