2013-09-26 2 views
0

CRITICAL_SECTION 클래스의 스레드 기능을 안전하게 수행하고 소켓 작업을 보내기/받기 하고 많은 작업을 수행 할 수 있지만 스레드가 로그 파일에 쓰는 경우 문제가 발생합니다. !다중 스레드 코드의 파일 I/O 문제

H

class ClassA 
{ 
public: 
    ClassA();  
    ~ClassA(); 

    void run(); 
    ... 

private: 
    CRITICAL_SECTION criticalSection; 
    LogFiles *m_logFiles; 
    ... 
}; 

CPP는

ClassA::ClassA() 
{ 
    m_logFiles = new LogFiles(); 
    InitializeCriticalSection(&criticalSection); 
} 

ClassA::~ClassA() 
{ 
    delete m_logFiles; 
    DeleteCriticalSection(&criticalSection); 
} 

void ClassA::run() 
{ 
    EnterCriticalSection(&criticalSection); 

    // do some stuff 
    m_logFiles->WriteToFile(message); 
    // do some stuff 
    m_logFiles->WriteToFile(message); 

    LeaveCriticalSection(&criticalSection); 
} 

로그 파일은 모든 정보 (4 개 쓰레드의 예 (2)로부터의 데이터 만) 또는 덮어 라인 (2 개 스레드가 동일한에서 작성한 포함 시각)!

그래서 LogFiles에서 WriteToFile 메서드를 보호해야한다고 생각하십니까?!

도움을 주셔서 감사합니다.

+0

각 스레드에서 클래스 A의 단일 (동일한) 객체를 사용 하시겠습니까? – AnatolyS

+1

모든 스레드는 동일한 'CRITICAL_SECTION' 개체를'잠금/잠금 해제 '해야합니다. 그들이 할 수 있다고 확신합니까? – HAL

+0

@AnatolyS : 예, 모든 스레드가 동일한 ClassA 객체를 사용합니다 – leon22

답변

0

뮤텍스 (예 : win32의 CRITICAL_SECTION)를 사용하여 로그 파일에 대한 액세스를 감싸거나 별도의 스레드를 사용하여 로그 파일 항목을 작성하십시오. 즉, 제공하는 스케치는 멀티 스레딩에 관한 한 정확합니다.

다른 중요한 문제가 있습니다. 첫째, 포인터 사용을 중지하십시오. 특히 "Type * t = new Type();"과 같은 Java/C# 코드를 작성하지 마십시오. 모든 곳에. 이로 인해 복잡성이 증가하고 메모리 누수가 발생합니다. 둘째, 자체 정의 유형의 복사 및 할당을 제어해야합니다. 예를 들어 ClassA 클래스는 복사 가능하지만 인스턴스는 독립적이지 않으므로 미묘한 버그 (포인터가 매달려 있거나 메모리 누수 등)가 발생할 수 있습니다.

C++ 문제를 해결해도 도움이되지 않는 경우 코드를 문제를 보여주는 최소한의 예에서 제외하고 여기에 게시하십시오.

4

CRITICAL_SECTION이 인스턴스 변수이기 때문에 각 ClassA 개체는 효과적으로 자체적 인 독립 뮤텍스를 갖습니다. 결과적으로 mutex를 잠그는 하나의 객체 (일명 중요한 영역으로 들어가는)는 다른 객체가 해당 개인 뮤텍스와 동일한 작업을 수행하는 것을 막지 않으며 공통 로그 파일 리소스는 완전히 보호되지 않습니다.

CRITICAL_SECTION을 클래스 정적 또는 기타 전역으로 설정하고 프로그램 시작 중에 초기화 할 수 있습니다. 내부적으로

LogFiles 클래스가 명시 적으로 (일명/휴가 입력)/잠금 해제를 잠금 자신의 CRITICAL_SECTION을 유지 (또는 더 나은, 그것을 관리하는 각 로그 파일 하나), 그리고 WriteToFile() 기능을 가지고위한 더 나은 선택이 될 수는 호출 될 때. 이렇게하면 리소스를 명시 적으로 사용자에게 요구하지 않고 리소스를 보호 할 수 있습니다. 따라서 항상 올바르게 작동하고 LogFile 클래스의 사용자에 대한 부담을 줄입니다.

+0

이것은 명백한 문제로 보일 수 있지만 OP는 모든 스레드가 클래스 객체의 단일 인스턴스를 사용하고 있다는 주석에서 설명합니다. 그는 어떻게 그렇게하는지 설명하지 않았습니다. –