파일이 메모리 매핑되었는지 어떻게 알 수 있나요?

파일이 메모리 매핑되었는지 어떻게 알 수 있나요?

메모리 매핑 파일에 대해 혼란스러워서 몇 가지 질문이 있습니다. 도움을 주시면 매우 기쁠 것입니다.

  1. 파일 시스템의 디렉터리를 탐색했는데 해당 디렉터리에 파일이 있다고 가정해 보겠습니다. 이 파일이 디스크 영역이 아닌 주 메모리 영역을 가리키는 것이 가능합니까?
  2. 이것이 가능하다면 이것이 우리가 "메모리 매핑 파일"이라고 부르는 것입니까?
  3. 파일 시스템에서 이러한 파일을 이동하는 목적은 무엇입니까(즉, 해당 파일을 한 디렉터리에서 다른 디렉터리로 이동하는 것) mv? 내가 이해하는 바는 파일이 메모리 매핑되어 있기 때문에 파일과 상호 작용하는 프로세스는 항상 주 메모리의 미리 정의된 영역에 기록하고 파일을 열 때(예: 를 vim사용하여 디스크가 포함되지 않음)라는 것입니다. 따라서 파일을 어디로 이동하더라도 항상 작동합니다. 그렇죠? 그렇다면 파일 시스템에서 파일을 이동하는 데 의미가 있습니까?
  4. 파일이 메모리 매핑되었는지 알 수 있는 명령이 있습니까?
  5. 마지막으로 를 사용하여 메모리 매핑된 파일을 열고 vim일부 변경한 후 저장하고 닫으면 vim어떻게 되나요 ? 내 변경 사항은 단순히 주 메모리에 기록됩니까? 이 경우 해당 파일을 사용하는 다른 프로세스에서 내가 방금 변경한 내용을 볼 수 있나요? 내 경험에 따르면, 파일을 일부 변경하면 다른 프로세스에서는 파일에 대한 변경 사항을 볼 수 없습니다 vim. 그 이유는 무엇입니까?

답변1

메모리 매핑 파일은 정확히 반대 방식으로 작동합니다. 메모리 매핑은 파일의 속성이 아니라 파일에 액세스하는 방법입니다. 프로세스는 파일의 내용(또는 파일의 하위 집합)을 주소 공간에 매핑할 수 있습니다. 이렇게 하면 파일을 더 쉽게 읽고 쓸 수 있습니다. 이렇게 하려면 메모리에서 읽고 쓰기만 하면 됩니다. 디스크에 있는 파일 자체는 다른 파일과 동일합니다.

이를 설정하기 위해 프로세스는 다음을 사용합니다.mmap기능. 이는 프로세스 간 메모리 공유와 같은 다른 목적으로도 사용될 수 있습니다.

답변2

메모리 매핑 파일은 (반드시) 메모리에서 지원되지 않습니다. 디스크에 완벽하게 존재합니다. 실제로 파일 위치는 파일 자체의 속성이 아니라 해당 파일이 있는 파일 시스템의 속성입니다.

메모리에 파일을 매핑하는 것은 프로세스가 파일의 일부를 메모리에 로드하기 위해 수행할 수 있는 작업입니다. 결과는 프로세스가 이 영역을 읽거나 쓸 때 실제로 파일을 읽고 쓰는 점을 제외하면 일반 메모리 영역과 비슷해 보입니다. 파일을 열고, 메모리에 매핑하고, 쓰고, 저장하면 수정 사항은 디스크의 파일에 적용됩니다(물론 디스크에 있는 경우).

read예를 들어, 메모리에서 읽고 쓰는 것이 , writellseek시스템 호출을 실행하는 것보다 빠르기 때문에 순차적이지 않은 파일에 대한 액세스가 많을 때 이 방법을 사용할 수 있습니다 . 이 접근 방식의 유일한 문제점은 동시에 파일을 읽거나 쓰기 위해 여러 프로세스가 필요한 경우 실제로 사용할 수 없다는 것입니다. 결과는 예측할 수 없습니다.

파일이 현재 매핑되었는지 여부를 알려줄 수 있는 명령은 없습니다. 그러나 프로세스의 매핑을 확인할 수 있습니다 /proc/<pid>/maps(시스템에 매핑이 있는 경우).

두 번째 질문에 대답하자면, 파일을 열 때 해당 파일을 파일 시스템으로 이동하더라도 해당 파일을 연 프로세스는 계속해서 해당 파일을 사용할 수 있습니다. 일어나는 일은 파일이 파일 시스템의 항목에 의존하지 않는다는 것입니다. 파일을 열자마자 파일 시스템의 경로가 변경되더라도 파일을 읽고 쓸 수 있는 파일 설명자인 "핸들"이 생깁니다. 파일은 파일 시스템에 항목이 없고 파일 설명자를 보유하는 프로세스가 없는 경우에만 사라집니다.

답변3

Q4: 파일이 메모리 매핑되었는지 확인하는 명령이 있습니까?

lsof명령은 현재 시스템에서 사용되는 모든 파일을 표시합니다. 파일이 메모리 매핑된 경우 "FD" 열에 "mem"이 포함됩니다. 따라서 이 명령의 출력을 grep하여 관심 있는 파일 이름을 찾을 수 있습니다.

답변4

메모리 상주 파일 시스템의 파일과 메모리 매핑 및 프로세스가 이동할 때 파일에 대한 액세스를 유지하는 방법과 같은 다른 개념을 혼동하는 것 같습니다.

나는 문제를 정리할 수 있는지 확인하기 위해 질문을 계속했습니다.

  1. 파일 시스템의 디렉터리를 탐색했는데 해당 디렉터리에 파일이 있다고 가정해 보겠습니다. 이 파일이 디스크 영역이 아닌 주 메모리 영역을 가리키는 것이 가능합니까?

일반적으로 /proc에 마운트되는 procfs, /sys에 마운트되는 sysfs, 때로는 /tmp에 마운트되는 tmpfs와 같은 메모리 상주 파일 시스템에 있는 경우 주 메모리를 가리킵니다.

  1. 이것이 가능하다면 이것이 우리가 "메모리 매핑 파일"이라고 부르는 것입니까?

아니요. Stephen-kitt가 말했듯이 "메모리 매핑"은 read() intoBlockWrite()와 같은 함수를 통해 한 번에 읽고 쓰는 것이 아니라 파일을 메인 메모리에 "매핑"하여 사용하여 액세스하는 방법을 의미합니다.

  1. 파일 시스템에서 이러한 파일을 이동하는 이유는 무엇입니까(즉, 해당 파일을 한 디렉터리에서 다른 디렉터리로 이동하는 것)? 내가 이해하기로는 파일이 메모리 매핑되어 있기 때문에 파일과 상호 작용하는 프로세스는 항상 미리 정의된 주 메모리 영역에 쓰고 파일을 열 때(예: vim을 사용하여) 주 메모리의 해당 영역을 읽습니다( 따라서 디스크가 포함되지 않습니다). 따라서 파일을 어디로 이동하더라도 항상 작동합니다. 그렇죠? 그렇다면 파일 시스템에서 파일을 이동하는 데 의미가 있습니까?

동일한 파일 시스템 내에서 이동하는 경우 실제로는 참조(즉, inode)를 한 디렉터리에서 다른 디렉터리로 이동하는 것입니다. 프로그램에 이미 파일이 열려 있는 경우 파일 설명자를 통해 이미 inode를 소유하고 있으므로 동일한 파일에 계속 액세스합니다. 귀하의 의견에서 언급한 table_name.idb 파일에서 이런 일이 발생합니다.

  1. 파일이 메모리 매핑되었는지 알 수 있는 명령이 있습니까?

Wossname은 메모리 매핑 파일에 대한 이 질문에 답변했습니다. lsof어떤 프로세스에 파일 메모리 매핑이 있는지 알려줍니다.

파일이 메모리 상주 파일 시스템에 있는지 확인하려면 파일 시스템과 해당 마운트 지점을 사용하거나 나열하면 df됩니다 . mount메모리에 어떤 유형의 파일 시스템이 있는지 알아보려면 Wikipedia 등을 검색하면 됩니다.

  1. 마지막으로 vim을 사용하여 메모리 매핑된 파일을 열고 일부 변경한 다음 vim을 저장하고 닫으면 어떻게 되나요? 내 변경 사항은 단순히 주 메모리에 기록됩니까? 이 경우 해당 파일을 사용하는 다른 프로세스에서 내가 방금 변경한 내용을 볼 수 있나요? 내 경험에 따르면 vim을 사용하여 파일을 일부 변경하면 다른 프로세스에서는 파일에 대한 변경 사항을 볼 수 없습니다. 그 이유는 무엇입니까?

mmap개인적으로 저는 C 프로그램에서 이 기능을 사용 하지 않았지만 제가 읽고 man mmap이해한 바에 따르면 info mmap메모리 내 표현을 동기화하는 데 필요한 마법은 없습니다. 기본 형식에서 mmap은 파일 내용을 메모리에 복사하기 위해 호출되며 msync메모리에서 디스크로 다시 쓰는 데 사용됩니다. 디스크의 파일이 변경되면 이를 감지하고 이를 매핑하는 모든 프로세스에서 메모리 내 표현을 자동으로 수정할 방법이 없습니다.

편집: mmap()은 실제로 특정 조건에서 메모리 내 표현을 동기화된 상태로 유지하려고 시도하는 것으로 나타났습니다. 매핑을 읽기만 하면 다른 프로세스가 파일에 쓰는 경우에도 동기화가 유지됩니다. 기록된 경우(메모리 영역에 할당하여) 발생하는 일은 명시적으로 필수인 MAP_SHARED 또는 MAP_PRIVATE 플래그 중 어느 것이 mmap()에 제공되는지에 따라 달라집니다. MAP_PRIVATE가 제공되면 맵은 온디스크 표현에서 분기되고 msync()를 사용할 때까지 동기화가 중지됩니다. MAP_SHARED가 제공되면 업데이트는 파일을 매핑하는 다른 프로세스와 (반드시 즉시는 아니지만) 디스크 표현에 표시됩니다.

방금 기존 파일에서 vim을 열고 e다른 터미널에서 명령을 실행했습니다. 몇 가지 이상한 부분을 제외하면 그것이 제가 얻은 가장 큰 부분입니다.:winotifywait -m .inotifywait

./ MOVED_FROM e
./ MOVED_TO e~
./ CREATE e
./ OPEN e
./ MODIFY e
./ CLOSE_WRITE,CLOSE e
./ ATTRIB e
./ ATTRIB e
./ DELETE e~

Vim은 새 파일을 만들고 이전 파일을 삭제합니다. 파일을 수정하는 대신 이 작업을 수행하는 이유는 이 질문의 범위를 벗어나지만 요점은 이것이 새 파일이므로 새 inode가 있다는 것입니다.

이제 다른 프로세스가 이 파일을 사용하고 있다는 것은 무엇을 의미합니까? 이 작업을 수행하는 동안 파일이 열려 있는 프로세스를 의미하는 경우 변경 사항이 표시되지 않습니다. 동일한 경로의 파일을 열어도 동일한 파일이 아니기 때문입니다. 이 작업을 수행한 후 파일을 열 수 있는 프로세스를 의미한다면 그렇습니다. 변경 사항이 표시됩니다. 귀하가 만든 새 파일이 열립니다.

프로그램이 사용자 인터페이스에서 파일을 여는 것처럼 보이지만 이것이 반드시 프로세스 중에 파일을 열어 둔다는 의미는 아닙니다. Vim은 위에 표시된 예입니다.

관련 정보