2013-03-06 4 views
0

현재 메모리 매핑 된 파일 주위에 머리를 얻고 잠재적으로 내 응용 프로그램에서 구현하려고합니다.메모리 매핑 된 파일 사용

응용 프로그램은 위치를 찾기 위해 일련의 큰 입력 파일을 사용합니다. 응용 프로그램이 단일 스레드에서 사용될 때 각 파일이 순차적으로 액세스됩니다. MMF가 보람있는 것처럼 보이는 더 많은 임의 액세스 영역이 생깁니다.

그러나 사용법에 대해 약간 혼란 스럽습니다. 각 스레드에서 MMF를 새로 작성해야합니까? 나는 그들이 모든 스레드에서 동일한 것을 원했고 그 MMF에 대한 각 스레드의 뷰를 생성하는 것처럼 보이는 것처럼 동일한 기본 파일을 공유 할 수 있다는 것을 알고 있습니다.

각 파일마다 하나만 만들어야하는 경우 MMF가 이미 만들어져 있는지 테스트 할 수있는 방법이 있습니다. 할당 된 이름이나 다른 방법을 사용하여 여러 파일을 같은 파일에 열지 못하게합니다. 또는 스레드에서 어떤 파일이 사용되고 중복을 방지하기 위해 이미 생성 된 인스턴스를 전달할 것인지 알 필요가 있습니까?

건배.

답변

2

각 스레드가 하나의 파일 전용 인 경우 각 스레드가 작업중인 하나의 파일에 대해 고유 한 MMF를 만드는 것이 좋습니다. 단일 스레드에서만 사용되는 리소스는 스레드 내에서 할당하고 파괴하기가 쉽습니다.

그러나 모든 스레드가 동일한 파일에서 읽는 경우 여러 MMF를 만들지는 않습니다. 소비하는 메모리 양을 늘리고 일관성 문제를 생성하기 때문입니다 (여러 개의 동일한보기 섹션).

같은 파일에서 작동하는 여러 스레드의 경우 MMF를 한 번 만들고 MMF 포인터를 여러 스레드와 공유해야합니다.

멀티 스레드 상황에서 요구에 따라 할당하는 작업은 복잡해지며 일반적으로 보호 된 리소스에 액세스 할 때마다 잠금이 필요합니다. 잠금을 요구하면 여러 개의 독립 스레드를 모두 실행하고 공유 자원에 대한 액세스를 기다려야하는 경우 성능상의 이점을 신속하게 무력화 할 수 있습니다.

스레드를 생성/시작하기 전에 공유 리소스를 할당 할 수 있다면 스레드가 스레드를 필요로 할 때까지 리소스가 항상 존재하므로 리소스 액세스를 잠그지 않아도됩니다.

그래서 스레드가 회전하고 잠금없이 모든 스레드에서 MMF 포인터를 공유하기 전에 MMF를 할당하는 것이 좋습니다.

또한이 파일은 엄격하게 읽기 전용이므로 여러 스레드가 절대로 파일이나 MMF에 다시 쓰지 않는다고 가정합니다. 다중 스레드는 스레드 동시성 문제없이 읽기 전용 액세스를 위해 공통 메모리 영역/MMF에 대한 포인터를 공유 할 수 있습니다.

전통적인 버퍼링 된 파일 액세스와 비교하여 MMF 성능에 대한 가정을주의하십시오.전체 파일 데이터가 사용 가능한 RAM에 적합하면 MMF는 버퍼링 된 파일 I/O보다 무작위 액세스 패턴에 더 효과적 일 수 있습니다. 파일 데이터가 사용 가능한 RAM보다 훨씬 큰 경우 버퍼링 된 파일 I/O는 MMF를 사용하는 것보다 임의 액세스에 대해 더 효율적일 수 있습니다. 왜? MMF는 메모리 사용에 대해 피기 때문에. MMF는 4k 페이지 크기의 청크로만 데이터를로드 할 수 있습니다. 버퍼링 된 파일 I/O는 실제 데이터 크기 요구 사항과 패턴에 맞게보다 세밀하게 조정할 수 있습니다. 응용 프로그램에서 파일의 100 개의 서로 다른 위치에서 512 바이트의 데이터를로드하는 경우 512x100 = 50k 데이터 만 필요하지만 MMF는 4k * 100 = 400k 바이트의 데이터를로드해야합니다. 이 데이터 액세스 패턴/사용 사례에서 MMF는 기존 파일 I/O보다 10 배 더 많은 데이터 전송 및 메모리 소비가 필요합니다.

MMF의 주된 매력은 원시 성능보다는 개발자 편의성입니다. 블록 지향 파일 I/O 하위 시스템을 작성하고 튜닝하는 것보다 MMF가 지원하는 포인터를 읽는 것이 일반적으로 개발자에게 더 편리합니다. 진실을 인정하는 한 개발자가 간단하고 편리하기 때문에 기술을 사용하는 데는 아무런 문제가 없습니다.

+0

철저한 답변 주셔서 감사합니다! 저는 파일을 읽는 것만으로 문제를 해결할 수 있습니다. MMF가 내 특정 인스턴스에 미친 영향을 살펴보고, 무엇보다 이해와 호기심을 위해이를 구현하려고합니다. 내가 오해한다면, 당신은 내가 포인터를 전달하는 것이 가장 좋다고 말합니다. MSDN 기사는 그것이 만들어 질 때 주어진 이름에 "OpenExisting"을 사용합니다 - 그 이름을 가진 MMF가 있는지 테스트 할 수있는 방법이 없습니까? 나는 그것이 쓰여지는 쓰레드가 될 때까지 어떤 파일을 사용할 지 모르겠다. –

+0

포인터 참조에 대해 유감스럽게 생각합니다. 이전 Win32 원시 코드 습관은 크게 어려워졌습니다. ;> – dthorpe

+1

내가 제안하는 것은 모든 스레드가 동일한 파일을 사용하고 데이터 읽기 만하는 경우라면 모든 스레드에서 하나의 MMF 인스턴스를 사용할 수 있습니다. 스레드가 시작되기 전에 MMF.CreateFromFile을 한 번 호출하고 모든 스레드와 해당 MMF 개체 인스턴스를 공유하십시오. 예를 들어 스레드가 도달 할 수있는 정적 변수에 MMF 개체를 채우십시오. MMF의 여러보기를 사용하지 않으려는 경우 모든 스레드에서 하나의보기를 공유 할 수도 있습니다. – dthorpe

0

프로세스의 스레드는 항상 동일한 주소 공간을 공유합니다. 즉, 모든 스레드가 전체 프로세스에 대해 "글로벌"인 개체 및 자원에 액세스 할 수 있습니다.

프로세스에서 파일에 대한 액세스를 동기화해야합니다. 모든 스레드에서 파일을 다시 열지는 못합니다. 특히 "더 큰"양 (수 MB)에 대해서 이야기 할 때 그렇습니다. MSDN은 주제에 대한 기사를 제공하므로 도움이 되길 바랍니다.

+0

MSDN 기사에서는 "OpenExisting"을 사용합니다.이 파일이 이미 존재한다는 것을 알고있는 경우 작동합니다. 제 경우에는 어떤 파일이 필요한지 알지 못합니다. 파일이 이미 열려 있는지 테스트 할 수 있습니까? –

+0

이것에 관해서는 FileStream.Open()을 사용하여 확인해야합니다. [Here] (http://stackoverflow.com/questions/876473/is-there-a-way-to-check-if-a-file-is-in-use)는 SO의 항목입니다. –

관련 문제