2014-11-20 2 views
5

스레드로 작업 중이므로 공유 리소스를 잠그는 데 뮤텍스를 사용합니다. 잠금의 기본 사용법은 리소스를 잠금/잠금 해제 블록에 넣는 것입니다. 항상 내가 단순 잠금에 대해 생각하기 시작 한 쌍의 잠금/잠금 해제가 있기 때문에단일 명령으로 리소스 잠금 및 잠금 해제

procedure RefreshData; 
begin  
    DataLock; 
     GetData; 
     GetSettings; 
     CheckValues; 
     ... 
    DataUnlock; 
end; 

/더 이상 필요하지 않을 때 자원의 잠금을 해제 화공 것 접근 방식의 잠금을 해제.

그래서 내 생각은 입력 매개 변수로 선행에 대한 참조를 취할 새로운 절차를 도입하는 것이 었습니다. 이것은 익명의 방법을 사용할 수있는 능력을 줄 것입니다.

type TBaseProc = reference to procedure; 

procedure TMyObject.LockMethod(AMeth: TBaseProc); 
begin 
    DataLock; 
    try 
    AMeth; 
    finally 
    DataUnlock; 
    end; 
end; 


procedure TForm1.RefreshData; 
begin 
    MyObject.LockMethod(
    procedure 
    begin 
    GetData; 
    GetSettings; 
    CheckValues; 
    ... 
    end; 
); 

end; 

어떤 의미를이 방법을 가지고하거나 더 나은 또는 더 쉽게 해결책이 :

코드 같은 것이 있을까요?

감사합니다.

+0

성능에 신경 써? –

+2

가장 쉬운 해결 방법은 컴파일러가 C#과 같은 Lock() 문을 네이티브로 지원하는지 여부입니다. http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx. 개인적으로 나는 잠금/잠금 해제 쌍에 대한 코드 템플릿을 사용합니다. –

+0

@David : 예 저는 성능에 관심이 있습니다. 얼마나 많은 오버 헤드가이 접근을 일으킬 수 있는지에 대한 평가가 있습니까? 잠금/잠금 해제 쌍이 여전히 성능면에서 더 나은 접근 방식이라고 생각합니다. – Nix

답변

0

이 방법은 완벽하지 않습니다. 코드에서 알 수 있듯이 전체 응용 프로그램 당 하나의 잠금 만 있기 때문입니다. 각각의 독립적 인 데이터 엔티티가 자체 잠금을 가지고있을 때 더 좋습니다. 따라서 다음과 같은 추상 클래스를 사용해야합니다.

type 
    TAbstractData = class 
    private 
     CriticalSection: TRtlCriticalSection 
    public 
     constructor Create; 
     procedure Lock; 
     procedure Unlock; 
     destructor Destroy; override; 
    end; 

그런 다음 잠금을 구현하는이 추상 클래스의 다른 클래스를 상속합니다.

 constructor TAbstractData .Create; 
     begin 
     inherited Create; 
     InitializeCriticalSection(CriticalSection); 
     end; 

     procedure TAbstractData.Lock; 
     begin 
     EntercriticalSection(CriticalSection); 
     end; 

     procedure TAbstractData.Unlock; 
     begin 
     LeaveSection(CriticalSection); 
     end; 

     procedure TAbstractData.Destroy; 
     begin 
     DeleteCriticalSection(CriticalSection); 
     inherited Destroy; 
     end; 

CriticalSection은 지금까지 Windows에서 구현 된 가장 효율적인 동기화 클래스입니다. 사실상 무료입니다 - 스레드 경합이 발생하지 않으면 거의 시스템 자원을 소비하지 않으며 단 하나의 스레드에서만 데이터를 사용할 때 값 비싼 컨텍스트 전환을 호출하지 않습니다.

답변을 제출 한 후 인터넷에서 좋은 기사 - http://blog.synopse.info/post/2016/01/09/Safe-locks-for-multi-thread-applications을 발견했습니다. 저자는 비슷한 접근 방식을 권장합니다.