Các gợi ý để tránh tài liệu tham khảo yếu không giải quyết cuộc đua vấn đề.
T1 operator new, create object, references: 1
T1 passes interface object reference to T2, thinking it can "share" ownership
T1 suspends
T2 resumes
T2 QueryInterface
T2 suspends before InterlockedIncrement, references: 1
T1 resumes
T1 Calls Release
T1 suspends between InterlockedDecrement and operator delete, references: 0
T2 resumes, InterlockedIncrement occurs, references 1
T2 suspends
T1 resumes, operator delete executes, references 1 !!!
T1 suspends
T2 resumes
T2 Any reference to the interface is now invalid since it has been deleted with reference count 1.
Đây là khả năng giải quyết trong máy chủ COM. Tuy nhiên, máy khách COM không nên phụ thuộc vào máy chủ ngăn chặn tình trạng chủng tộc này. Do đó, COM clients KHÔNG PHẢI chia sẻ các đối tượng giao diện giữa các luồng. Chủ đề duy nhất được phép truy cập đối tượng giao diện, là chuỗi ONE hiện đang "sở hữu" đối tượng giao diện.
T1 KHÔNG được gọi là Bản phát hành. Có, nó có thể được gọi là AddRef trước khi truyền đối tượng giao diện cho T2. Nhưng điều đó có thể không giải quyết được cuộc đua, chỉ di chuyển nó ở đâu đó khác. Cách tốt nhất là luôn duy trì khái niệm về một đối tượng giao diện, một chủ sở hữu.
Nếu máy chủ COM muốn hỗ trợ khái niệm hai (hoặc nhiều hơn) giao diện có thể tham khảo một số trạng thái nội bộ của máy chủ được chia sẻ, máy chủ COM nên quảng cáo hợp đồng bằng cách cung cấp phương thức CreateCopyOfInstance và quản lý tranh chấp, nội bộ. Có, tất nhiên, ví dụ về các máy chủ xử lý loại "fan-out" này. Hãy xem các giao diện lưu trữ liên tục từ Microsoft. Ở đó, các giao diện KHÔNG "gây ra" .. mỗi giao diện nên được sở hữu bởi một người dùng đơn lẻ (thread/process/whatever) và "fan-out" được quản lý, nội bộ, bởi máy chủ, với các phương thức được cung cấp cho COM khách hàng để kiểm soát một số khía cạnh của các vấn đề tranh chấp. Do đó, các máy chủ COM của Microsoft phải giải quyết các điều kiện cuộc đua như một phần hợp đồng của họ với khách hàng của họ.
Ahh ... vì vậy đó là do luồng, tôi đã không nhận ra điều đó. Cảm ơn! +1 – Mehrdad
Thậm chí không phân luồng, nếu bạn 'Release' của bạn * mạnh * (chúng ta hãy gọi nó) tham chiếu trước * yếu * một sau đó tham chiếu * yếu * không còn giá trị. Gọi 'Release' về cơ bản là cách nói của bạn" okay tôi đã làm "- một khi bạn gọi nó, ngừng sử dụng đối tượng. Nếu bạn cần tiếp tục sử dụng đối tượng ... đừng gọi 'Release'. –
Phải; Tôi chỉ tự hỏi về trường hợp bạn gọi là 'Release' trên giao diện mới * ngay lập tức sau cuộc gọi 'QueryInterface' của bạn, và vì vậy đó là lý do tại sao tôi không nghĩ đến một điều kiện chủng tộc. – Mehrdad