|
답변:
Synchronize() 함수는 메인 쓰레드가 아닌 다른 쓰레드에서 어떤 코드를... 메인 쓰레드 Context로 실행하기 위해 만들어진 거고...
VCL 클래스 라이브러리가 쓰레드 세이프로 구현되어 있지 않기 때문에... VCL 클래스 라이브러리에 래핑되어 있는 윈도우즈 유저
인터페이스를 지원하기 위한 코드들 또한 쓰레드 세이프가 아니라... 다른 쓰레드에서 VCL UI 코드를 메인 쓰레드 Context로 실행
되게 할 때 주로 쓰이고 쓰레드 전환을 위해 컨텍스트 스위칭이 필요하게 되죠.
Synchronize()로 실행되는 코드가 길면 길수록 그에 따라... 쓰레드의 다른 부분의 코드실행은 그 시간동안 블러킹 상태가 되게
됩니다. (임계영역을 잘개 쪼개지 않고 싱글 락 하나로 전체 영역을 블러킹 상태로 만들어서)
VCL 라이브러리가 쓰레드 세이프로 만들어져 있지 않기 때문에... 다른 쓰레드에서 VCL 코드를 사용할 수 있도록 하기 위한
고육지책으로 Synchronize() 함수를 구현해 놓은 건데... 상당히 비효율적인 방식이 되고 맙니다.
질문에 언급된 것 처럼...
메인쓰레드는 데이타를 Add만 하고, 다른 쓰레드는 Add된 데이타를 갖고 별도의 처리를 하는 경우...
즉..하나의 쓰레드는 Push만 하고, 다른 쓰레드는 Pop만 하는 경우...
다시 말해서... 두개의 쓰레드 중...
메인 쓰레드의 Push()는 TAIL 만 변경하고, 다른 쓰레드의 Pop()은 HEAD만 변경한다는 것에 착안해서...
CriticalSection, Mutex, Semaphore 등의 동기화 코드를 전혀 사용하지 않고도..
Lock-Free 형태의 Thread Safe 원형 버퍼를 만들어서 사용하는 게 가능 하지요.
퍼포먼스 또한 당연히 빠를 수 밖에 없고요. (Lock-Free Thread Safe 버퍼 구현 쪽으로 공부를 해 보세요)
C++11을 이용하면 퍼포먼스를 위한 쓰레드 세이프 코드 구현에서 유리한 점이 많은데 STL을 깊이 있게 다뤄 보기 바랍니다.
그린비 님이 쓰신 글 :
: 안녕하세요~ 더운 날씨에 노고가 많으십니다~~!
:
: 전역으로 선언한 StringList가 있고요.
: 여기에 로그를 Add 하고 파일 저장 후 서버에 전송하는 게 목적입니다.
:
:
: 1) 메인 프로세스에서는 StringList에 Add 만 합니다.
: 2) 추가 쓰레드에서는 StringList를 주기적으로 파일 저장을 하고, 서버에 전송을 합니다.
:
: <질문 1>
: 여기에서 문제가 예상되는게, 메인프로세스에서 StringList에 Add를 하는 도중에
: 만약 추가 쓰레드가 StringList에 접근해서 파일저장을 하려고 하면 동기화가 안지켜 질 것 같은데요..
: 정말 그런가요?
:
: <질문2>
: 해결 하려면 메인프로세스에서 파일을 저장하고, 추가 쓰레드에서 서버에 전송을 하게 하면
: 해결이 될까요?
:
:
: 관심 부탁드립니다~~~
|