2014-12-05 2 views
1

이 질문은 매우 간단 할 수 있지만 여전히 효율적인 방법을 찾아 낼 수는 없습니다. 다음과 같은 설정이 있습니다 :메모리 버퍼에 대한 효율적인 다중 스레드 공유 액세스

1) 스레드 A는 인터넷에서 메모리 버퍼로 끊임없이 데이터를 다운로드합니다.

2) 동시에 스레드 B는이 버퍼에서 이미 다운로드 한 데이터를 읽으려고합니다.

버퍼가 원형이 아니거나 아무것도 아닙니다. 쓰기 커서와 읽기 커서가 있습니다. 일단 스레드 A가 버퍼에 무엇인가를 기록하면 쓰기 커서를 갱신하여 스레드 B가 현재 읽을 수있는 데이터의 양을 알려줍니다.

문제는 스레드 B가 종종 수천 바이트를 읽지 만 한 번에 한 바이트 씩 읽는 것입니다. 따라서 두 스레드를 효율적으로 동기화하는 방법이 필요합니다. 이미 SetEvent() 및 WaitForSingleObject() 시도했지만 꽤 느린 (또는 나는 뭔가 잘못한) 스레드 B 버퍼에서 1 바이트의 패킷을 읽을 수 있으므로 스레드 B가 WaitForSingleObject() 모든 바이트 그것을 호출 할 수 있기 때문에 읽어야합니다. 오버 헤드가 많이 들리는 것 같습니다.

뮤텍스 (중요 섹션) 보호없이이 작업을 수행 할 수 있습니까? 즉 스레드 B는 충분한 데이터가 이용 가능할 때까지 쓰기 커서를 폴링 한 다음 복사 할 수 있습니다. 그러나 동기화 문제가 발생합니다. 즉 스레드 A가 쓰기 커서를 업데이트하면이 변경 내용이 스레드 B에 즉시 반영됩니까? 필자는 멀티 스레딩 프로그래밍에 대한 많은 경험이 없으며 많은 기사를 매우 복잡하게 들려서 효율적으로 구현할 수있는 누군가를 올바른 방향으로 안내 할 수 있다면 기쁠 것입니다.

+1

이렇게하지 않으려 고 노력하십시오. 데이터는 일반적으로 1 바이트보다 훨씬 큰 청크로 네트워크에서 읽습니다. 정말로 버퍼 하나만 사용해야합니까? 스레드 A는 왜 동적으로 할당 된 버퍼 구조체/인스턴스, 대기열 차단 (생성자 - 소비자 대기열 차단), 스레드 B의 버퍼 포인터로 큰 덩어리를 읽고 다음 데이터로드를 위해 새 버퍼를 즉시 할당 할 수 있습니까? 단일 바이트에 대한 스레드 간 통신은 사용자의 작업 방식에 관계없이 매우 비효율적입니다. –

+0

고마워, 그게 내가 지금하고있는거야. 스트림 스레드에서 16kb의 패킷을 읽고 주 프로그램에서 빠른 바이트 기반 액세스를 위해 이러한 패킷을 버퍼링. 이것은 효율적이고 더 좋은 접근 방법입니다. – Andreas

답변

0

예, 뮤텍스가 필요없이 다른 스레드에서 변경 한 사항을 한 스레드에서 폴링 할 수 있습니다. 이것은 매우 빠르지 만 스레드 B가 끊임없이 새 데이터를 확인하기 위해 폴링 할 때 CPU 오버 헤드가 높습니다.

+0

하지만 데이터가 즉시 동기화 되었습니까? 스레드 A의 변수에 대한 변경 사항은 스레드 B가 즉시 사용할 수 없다는 것을 원격으로 기억합니다. AFAIR 동기화는 잠시 동안 또는 절전 (0) 또는 이와 유사한 작업을 수행 할 때만 발생하지만 여기서 틀릴 수도 있습니다. – Andreas

+0

예. 즉시 동기화됩니다. –

+0

CPU에 따라 다르지만 괜찮은 CPU는 즉시 동기화됩니다. –

관련 문제