Tôi có một cá thể lớp được sử dụng bởi một số lớp khác trong các chủ đề khác để giao tiếp.Điều gì có thể gây ra bế tắc của một khóa đọc/ghi nhiều lần?
lớp này sử dụng một đầu đọc mỏng/khóa nhà văn (WinAPI của SRWLOCK
) như là một đối tượng đồng bộ hóa và một vài lớp helper RAII để thực sự khóa/mở khóa điều:
static unsigned int readCounter = 0;
class CReadLock
{
public:
CReadLock(SRWLOCK& Lock) : m_Lock(Lock) { InterlockedIncrement(&readCounter); AcquireSRWLockShared(&m_Lock); }
~CReadLock() {ReleaseSRWLockShared(m_Lock); InterlockedDecrement(&readCounter);}
private:
SRWLOCK& m_Lock;
};
class CWriteLock
{
public:
CWriteLock(SRWLOCK& Lock) : m_Lock(Lock) { AcquireSRWLockExclusive(&m_Lock); }
~CWriteLock() { ReleaseSRWLockExclusive(&m_Lock); }
private:
SRWLOCK& m_Lock;
};
Vấn đề là điều bế tắc toàn bộ mọi lúc. Khi tôi tạm dừng chương trình bế tắc, tôi thấy:
- một sợi bị kẹt trong
AcquireSRWLockExclusive()
; - hai chủ đề bị kẹt trong
AcquireSRWLockShared()
; readCounter
toàn cầu được thiết lập để 3.
Con đường tôi nhìn thấy nó, cách duy nhất để điều này xảy ra là destructor CReadLock
sơ thẩm chưa được gọi là bằng cách nào đó một nơi nào đó khóa là vĩnh viễn bị mắc kẹt. Tuy nhiên, cách duy nhất để điều này xảy ra (theo như tôi biết) là vì một ngoại lệ đã bị ném. Nó không phải. Tôi đã kiểm tra.
Điều gì có thể là vấn đề? Làm thế nào tôi nên đi về sửa chữa (hoặc ít nhất là định vị lý do) điều này?
Không nên 'bar' chỉ nhận khóa? Ngoài ra nó có thể có thể bế tắc nếu 'foo' gọi' baz' (Không biết khóa có đệ quy) – Lol4t0
Không cần thiết, 'GetireSRWLockShared' của Win32 API không được đệ quy ** không giống như 'pthread_rwlock_rdlock' hoặc' EnterCriticalSection' của POSIX – Artyom
Bạn có thể chứng minh rằng 'baz yêu cầu tạo khóa ghi bây giờ tất cả các khóa đọc sẽ chặn cho đến khi tất cả được phát hành - chờ đợi.'? Bởi vì MSDN [nói] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937%28v=vs.85%29.aspx): 'Không có gì đảm bảo về thứ tự trong đó chủ đề yêu cầu quyền sở hữu sẽ được cấp quyền sở hữu; Ổ khóa SRW không công bằng hay FIFO. ' – Lol4t0