중요한 클래스와 잠금을 관리해야하는 간단한 클래스를 찾고 있는데,이를 테스트 사례로 다뤄보고 싶습니다. 이것이 의미가 있으며, 어떻게해야 할 것입니까? 클래스 작업을 확인하는 유일한 방법은 매우 복잡한 스레딩 시나리오를 설정하는 것이므로 Win32에서 중요한 섹션의 누수를 테스트하는 좋은 방법이 아니기 때문에 어렵습니다. 올바르게 작동하는지 직접 확인하는 방법이 있습니까? 여기 단위 테스트 Refcounted Critical Section 클래스
코드입니다 :CriticalSection.hpp :
#pragma once
#include <windows.h>
#include <boost/shared_ptr.hpp>
namespace WindowsAPI { namespace Threading {
class CriticalSectionImpl;
class CriticalLock;
class CriticalAttemptedLock;
class CriticalSection
{
friend class CriticalLock;
friend class CriticalAttemptedLock;
boost::shared_ptr<CriticalSectionImpl> impl;
void Enter();
bool TryEnter();
void Leave();
public:
CriticalSection();
};
class CriticalLock
{
CriticalSection &ref;
public:
CriticalLock(CriticalSection& sectionToLock) : ref(sectionToLock) { ref.Enter(); };
~CriticalLock() { ref.Leave(); };
};
class CriticalAttemptedLock
{
CriticalSection &ref;
bool valid;
public:
CriticalAttemptedLock(CriticalSection& sectionToLock) : ref(sectionToLock), valid(ref.TryEnter()) {};
bool LockHeld() { return valid; };
~CriticalAttemptedLock() { if (valid) ref.Leave(); };
};
}}
CriticalSection.cpp :
#include "CriticalSection.hpp"
namespace WindowsAPI { namespace Threading {
class CriticalSectionImpl
{
friend class CriticalSection;
CRITICAL_SECTION sectionStructure;
CriticalSectionImpl() { InitializeCriticalSection(§ionStructure); };
void Enter() { EnterCriticalSection(§ionStructure); };
bool TryEnter() { if (TryEnterCriticalSection(§ionStructure)) return true; else return false; };
void Leave() { LeaveCriticalSection(§ionStructure); };
public:
~CriticalSectionImpl() { DeleteCriticalSection(§ionStructure); };
};
void CriticalSection::Enter() { impl->Enter(); };
bool CriticalSection::TryEnter() { return impl->TryEnter(); };
void CriticalSection::Leave() { impl->Leave(); };
CriticalSection::CriticalSection() : impl(new CriticalSectionImpl) {} ;
}}
몇 가지 문제가 있습니다. #1. CRITICAL_SECTION 구조는 이동하거나 복사 할 수 없습니다. 그것이 처음부터 참조 횟수를 늘리는 이유입니다. 그러므로 클라이언트가 클래스의 메모리 관리에 대해 걱정할 필요가 없기 때문에 여기에서 다시 계산하는 것이 필수적입니다. # 2 : 자물쇠 취급이 훨씬 낫습니다. 고맙습니다. # 3 : API 함수를 조롱하는 방법을 살펴 보겠습니다. 중요한 부분 객체의 절반 정도가 코드를 사용하여 코드를 테스트 할 수 있기 때문에 아이러니합니다. –
나는 # 1이 문제가되는 것을 결코 발견하지 못했다. 아마 그것은 내가 자물쇠를 사용하는 방법 일뿐입니다. 단순히 자신의 영역을 잠그고 RAII '소유자'클래스를 사용하여 잠금 수명을 관리 할 수 있어야하는 클래스에 'CCriticalSection'인스턴스를 추가하기 만하면됩니다. 자체 잠금을 가진 객체의 경우 거의 사본 또는 할당 op가 없습니다. 그것은 단지 의미가 없기 때문에 문제가 없으며 참조 카운트가 필요하지 않습니다. –
중요한 섹션 객체를 복사 불가능하게 만들 수 있다고 생각하지만 지금은 실제로 필요한 시나리오에 있습니다. 임계 섹션 객체는 "shared_ptr"의미를 갖는다. 중요한 부분에 특별한 해체가 필요하지 않다면 나는'shared_ptr'을 사용하여 끝내 겠지만 불행히도 그들은 다음과 같이합니다 : ( –