mmap — 메모리 매핑 파일 지원
mmap — 메모리 매핑 파일 지원
사용 가능: WASI는 제외. 이 모듈은 WebAssembly에서 동작하지 않거나 사용할 수 없어요.
메모리 매핑 파일 객체는 bytearray처럼도, 파일 객체처럼도 동작해요. bytearray가 기대되는 대부분의 곳에서 mmap 객체를 사용할 수 있어요. 예를 들어 re 모듈로 메모리 매핑 파일을 검색할 수 있어요. obj[index] = 97로 단일 바이트를 바꾸거나, obj[i1:i2] = b'...'처럼 슬라이스에 할당해 부분 시퀀스를 바꿀 수도 있어요. 현재 파일 위치부터 데이터를 읽고 쓸 수 있고, seek()로 파일의 다른 위치로 이동할 수도 있어요.
메모리 매핑 파일은 Unix와 Windows에서 다른 mmap 생성자로 만들어져요. 어느 쪽이든 업데이트용으로 열린 파일의 파일 디스크립터를 제공해야 해요. 기존 Python 파일 객체를 매핑하려면 그 fileno() 메서드를 사용해 fileno 매개변수에 넣을 올바른 값을 얻어요. 아니면 os.open() 함수로 파일을 열어 파일 디스크립터를 직접 얻을 수 있어요(여전히 쓴 다음 닫아야 해요).
참고: 쓰기 가능한 버퍼링된 파일에 메모리 매핑을 만들려면 먼저 파일을
flush()해야 해요. 버퍼의 로컬 수정이 실제로 매핑에서 사용 가능하도록 보장하는 데 필요해요.
Unix와 Windows 생성자 모두에서 access를 선택적 키워드 매개변수로 지정할 수 있어요. access는 네 값 중 하나를 받아요: ACCESS_READ, ACCESS_WRITE, ACCESS_COPY는 각각 읽기 전용, write-through(직접 기록), copy-on-write(복사 시 쓰기) 메모리를 지정하고, ACCESS_DEFAULT는 prot에 위임해요. access는 Unix와 Windows 둘 다에서 쓸 수 있어요. access를 지정하지 않으면 Windows mmap은 write-through 매핑을 돌려줘요. 세 access 타입 모두의 초기 메모리 값은 지정된 파일에서 가져와요. ACCESS_READ 메모리 맵에 할당하면 TypeError 예외가 나요. ACCESS_WRITE 메모리 맵에 할당하면 메모리와 밑바탕 파일에 모두 영향을 줘요. ACCESS_COPY 메모리 맵에 할당하면 메모리에는 영향을 주지만 밑바탕 파일을 갱신하지는 않아요.
버전 3.7에서 변경: ACCESS_DEFAULT 상수 추가.
익명 메모리를 매핑하려면 fileno로 -1과 길이(length)를 전달하면 돼요.
출처: Python 표준 라이브러리
본문
class mmap.mmap(fileno, length, tagname=None, access=ACCESS_DEFAULT, offset=0)
(Windows 버전) 파일 핸들 fileno가 지정하는 파일에서 length 바이트를 매핑하고 mmap 객체를 만들어요. length가 파일의 현재 크기보다 크면 파일은 length 바이트를 담도록 확장돼요. length가 0이면 맵의 최대 길이는 파일의 현재 크기인데, 파일이 비어 있으면 Windows는 예외를 일으켜요(Windows에서는 빈 매핑을 만들 수 없어요).
tagname이 지정되고 None이 아니면 매핑에 대한 태그 이름을 주는 문자열이에요. Windows는 같은 파일에 대해 여러 매핑을 가질 수 있게 해 줘요. 기존 태그의 이름을 지정하면 그 태그가 열리고, 아니면 이 이름의 새 태그가 만들어져요. 이 매개변수를 생략하거나 None이면 이름 없는 매핑이 만들어져요. tagname 매개변수 사용을 피하면 코드를 Unix와 Windows 사이에 이식 가능하게 유지하는 데 도움이 돼요.
offset은 음이 아닌 정수 오프셋으로 지정할 수 있어요. mmap 참조는 파일 시작부터의 offset에 상대적이에요. offset의 기본값은 0이고 ALLOCATIONGRANULARITY의 배수여야 해요. 인자 fileno, length, access, offset으로 auditing 이벤트 mmap.__new__를 일으켜요.
class mmap.mmap(fileno, length, flags=MAP_SHARED, prot=PROT_WRITE | PROT_READ, access=ACCESS_DEFAULT, offset=0, *, trackfd=True)
(Unix 버전) 파일 디스크립터 fileno가 지정하는 파일에서 length 바이트를 매핑하고 mmap 객체를 돌려줘요. length가 0이면 맵의 최대 길이는 mmap이 호출될 때 파일의 현재 크기가 돼요.
flags는 매핑의 성격을 지정해요. MAP_PRIVATE는 개인 copy-on-write 매핑을 만들어서 mmap 객체 내용의 변경이 이 프로세스에만 비공개로 되고, MAP_SHARED는 파일의 같은 영역을 매핑하는 모든 다른 프로세스와 공유되는 매핑을 만들어요. 기본값은 MAP_SHARED예요. 어떤 시스템에는 전체 목록이 MAP_* 상수에 지정된 추가 플래그가 있을 수 있어요.
prot을 지정하면 원하는 메모리 보호를 주고, 가장 유용한 두 값은 페이지를 읽거나 쓸 수 있게 지정하는 PROT_READ와 PROT_WRITE예요. prot의 기본값은 PROT_READ | PROT_WRITE예요.
access는 flags와 prot 대신 선택적 키워드 매개변수로 지정할 수 있어요. flags, prot, access를 모두 지정하는 건 오류예요. 이 매개변수 사용법은 위의 access 설명을 참고하세요.
offset은 음이 아닌 정수 오프셋으로 지정할 수 있어요. mmap 참조는 파일 시작부터의 offset에 상대적이에요. offset의 기본값은 0이고, Unix 시스템에서 PAGESIZE와 같은 ALLOCATIONGRANULARITY의 배수여야 해요.
trackfd가 False이면 fileno가 지정하는 파일 디스크립터가 복제되지 않고, 결과 mmap 객체가 맵의 밑바탕 파일과 연결되지 않아요. 이는 size()와 resize() 메서드가 실패한다는 뜻이에요. 이 모드는 열린 파일 디스크립터 수를 제한하는 데 유용해요. 만들어진 메모리 매핑의 유효성을 보장하기 위해 디스크립터 fileno가 지정하는 파일은 macOS에서 내부적으로 물리 backing store와 자동 동기화돼요.
버전 3.13에서 변경: trackfd 매개변수 추가.
간단한 mmap 사용 예:
import mmap
# write a simple example file
with open("hello.txt", "wb") as f:
f.write(b"Hello Python!\n")
with open("hello.txt", "r+b") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0)
# read content via standard file methods
print(mm.readline()) # prints b"Hello Python!\n"
# read content via slice notation
print(mm[:5]) # prints b"Hello"
# update content using slice notation;
# note that new content must have same size
mm[6:] = b" world!\n"
# ... and read again using standard file methods
mm.seek(0)
print(mm.readline()) # prints b"Hello world!\n"
# close the map
mm.close()
mmap은 with 문에서 컨텍스트 매니저로도 쓸 수 있어요:
import mmap
with mmap.mmap(-1, 13) as mm:
mm.write(b"Hello world!")
버전 3.2에서 추가: 컨텍스트 매니저 지원.
다음 예는 익명 맵을 만들고 부모-자식 프로세스 사이에서 데이터를 교환하는 방법을 보여 줘요:
import mmap
import os
mm = mmap.mmap(-1, 13)
mm.write(b"Hello world!")
pid = os.fork()
if pid == 0: # In a child process
mm.seek(0)
print(mm.readline())
mm.close()
인자 fileno, length, access, offset으로 auditing 이벤트 mmap.__new__를 일으켜요.
메모리 매핑 파일 객체는 다음 메서드를 지원해요.
close()
mmap을 닫아요. 이후 객체의 다른 메서드 호출은 ValueError 예외가 나요. 열린 파일은 닫지 않아요.
closed
파일이 닫혔으면 True. 버전 3.2에 추가됨.
find(sub[, start[, end]])
부분 시퀀스 sub가 범위 [start, end]에 포함되도록 발견되는 객체의 가장 낮은 인덱스를 돌려줘요. 선택 인자 start와 end는 슬라이스 표기처럼 해석돼요. 실패하면 -1을 돌려줘요.
버전 3.5에서 변경: 쓰기 가능한 bytes-like 객체가 이제 받아들여짐.
flush()
flush(offset, size, /)
파일의 메모리 내 사본에 가한 변경을 디스크로 되돌려 써요. 이 호출을 사용하지 않으면 객체가 파괴되기 전에 변경이 기록된다는 보장이 없어요. offset과 size를 지정하면 주어진 바이트 범위의 변경만 디스크로 플러시되고, 아니면 매핑 전체 범위가 플러시돼요. offset은 PAGESIZE 또는 ALLOCATIONGRANULARITY의 배수여야 해요. 성공을 나타내려면 None이 반환되고, 호출이 실패하면 예외가 나요.
버전 3.8에서 변경: 이전에는 성공 시 0이 아닌 값이 반환됐고 Windows에서는 오류 시 0이 반환됐음. Unix에서는 성공 시 0, 오류 시 예외가 발생했음.
madvise(option[, start[, length]])
start에서 시작해 length 바이트까지 뻗는 메모리 영역에 대해 커널에 조언 option을 보내요. option은 시스템에서 사용 가능한 MADV_* 상수 중 하나여야 해요. start와 length를 생략하면 전체 매핑이 대상이 돼요. 일부 시스템(Linux 포함)에서는 start가 PAGESIZE의 배수여야 해요.
사용 가능: madvise() 시스템 호출이 있는 시스템. 버전 3.8에 추가됨.
move(dest, src, count)
src 오프셋에서 시작하는 count 바이트를 목적지 인덱스 dest로 복사해요. mmap이 ACCESS_READ로 만들어졌으면 move 호출은 TypeError 예외를 일으켜요.
read([n])
현재 파일 위치부터 최대 n 바이트를 담은 bytes를 돌려줘요. 인자를 생략하거나 None이나 음수이면 현재 파일 위치부터 매핑 끝까지의 모든 바이트를 돌려줘요. 파일 위치는 돌려진 바이트 뒤를 가리키도록 갱신돼요.
버전 3.3에서 변경: 인자를 생략하거나 None 가능.
read_byte()
현재 파일 위치의 바이트를 정수로 돌려주고 파일 위치를 1만큼 전진시켜요.
readline()
현재 파일 위치에서 다음 줄바꿈까지의 단일 줄을 돌려줘요. 파일 위치는 돌려진 바이트 뒤를 가리키도록 갱신돼요.
resize(newsize)
맵과 그 밑바탕 파일(있으면)의 크기를 바꿔요. ACCESS_READ 또는 ACCESS_COPY access로 만든 맵의 크기를 바꾸면 TypeError 예외가 나요. trackfd를 False로 설정해 만든 맵의 크기를 바꾸면 ValueError 예외가 나요.
Windows에서: 같은 이름의 파일에 다른 맵이 있으면 맵 크기 변경이 OSError를 일으켜요. 익명 맵(pagefile에 대한)의 크기 변경은 새 크기 길이까지 원본 데이터를 복사해 새 맵을 조용히 만드는 결과가 돼요.
버전 3.11에서 변경: 다른 맵이 잠겨 있을 때 크기 변경을 시도하면 올바르게 실패. Windows에서 익명 맵에 대한 크기 변경 허용.
rfind(sub[, start[, end]])
부분 시퀀스 sub가 범위 [start, end]에 포함되도록 발견되는 객체의 가장 높은 인덱스를 돌려줘요. 선택 인자 start와 end는 슬라이스 표기처럼 해석돼요. 실패하면 -1을 돌려줘요.
버전 3.5에서 변경: 쓰기 가능한 bytes-like 객체가 이제 받아들여짐.
seek(pos[, whence])
파일의 현재 위치를 설정해요. whence 인자는 선택이고 기본값은 os.SEEK_SET 또는 0(절대 파일 위치 지정)이에요. 다른 값은 os.SEEK_CUR 또는 1(현재 위치 기준)과 os.SEEK_END 또는 2(파일 끝 기준)예요.
버전 3.13에서 변경: None 대신 새 절대 위치를 반환.
seekable()
파일이 seek을 지원하는지 돌려주고, 반환값은 항상 True예요. 버전 3.13에 추가됨.
size()
파일의 길이를 돌려줘요. 메모리 매핑 영역의 크기보다 클 수 있어요.
tell()
파일 포인터의 현재 위치를 돌려줘요.
write(bytes)
bytes의 바이트를 파일 포인터의 현재 위치의 메모리에 쓰고 쓴 바이트 수를 돌려줘요(len(bytes)보다 작을 수 없어요, 쓰기가 실패하면 ValueError가 나기 때문이에요). 파일 위치는 쓰인 바이트 뒤를 가리키도록 갱신돼요. mmap이 ACCESS_READ로 만들어졌으면 쓰기는 TypeError 예외를 일으켜요.
버전 3.5에서 변경: 쓰기 가능한 bytes-like 객체가 이제 받아들여짐. 버전 3.6에서 변경: 쓰인 바이트 수가 이제 반환됨.
write_byte(byte)
정수 byte를 파일 포인터의 현재 위치의 메모리에 써요. 파일 위치는 1만큼 전진해요. mmap이 ACCESS_READ로 만들어졌으면 쓰기는 TypeError 예외를 일으켜요.
MADV_* 상수
mmap.MADV_NORMAL, mmap.MADV_RANDOM, mmap.MADV_SEQUENTIAL, mmap.MADV_WILLNEED, mmap.MADV_DONTNEED, mmap.MADV_REMOVE, mmap.MADV_DONTFORK, mmap.MADV_DOFORK, mmap.MADV_HWPOISON, mmap.MADV_MERGEABLE, mmap.MADV_UNMERGEABLE, mmap.MADV_SOFT_OFFLINE, mmap.MADV_HUGEPAGE, mmap.MADV_NOHUGEPAGE, mmap.MADV_DONTDUMP, mmap.MADV_DODUMP, mmap.MADV_FREE, mmap.MADV_NOSYNC, mmap.MADV_AUTOSYNC, mmap.MADV_NOCORE, mmap.MADV_CORE, mmap.MADV_PROTECT, mmap.MADV_FREE_REUSABLE, mmap.MADV_FREE_REUSE
이 옵션들은 mmap.madvise()에 전달할 수 있어요. 모든 옵션이 모든 시스템에 있는 건 아니에요.
사용 가능: madvise() 시스템 호출이 있는 시스템. 버전 3.8에 추가됨.
MAP_* 상수
mmap.MAP_SHARED, mmap.MAP_PRIVATE, mmap.MAP_32BIT, mmap.MAP_ALIGNED_SUPER, mmap.MAP_ANON, mmap.MAP_ANONYMOUS, mmap.MAP_CONCEAL, mmap.MAP_DENYWRITE, mmap.MAP_EXECUTABLE, mmap.MAP_HASSEMAPHORE, mmap.MAP_JIT, mmap.MAP_NOCACHE, mmap.MAP_NOEXTEND, mmap.MAP_NORESERVE, mmap.MAP_POPULATE, mmap.MAP_RESILIENT_CODESIGN, mmap.MAP_RESILIENT_MEDIA, mmap.MAP_STACK, mmap.MAP_TPRO, mmap.MAP_TRANSLATED_ALLOW_EXECUTE, mmap.MAP_UNIX03
이들은 mmap.mmap()에 전달할 수 있는 다양한 플래그예요. MAP_ALIGNED_SUPER는 FreeBSD에서만, MAP_CONCEAL은 OpenBSD에서만 사용 가능해요. 일부 옵션이 일부 시스템에 없을 수 있음에 주의하세요.
버전 3.10에서 변경: MAP_POPULATE 상수 추가.
버전 3.11에서 추가: MAP_STACK 상수.
버전 3.12에서 추가: MAP_ALIGNED_SUPER와 MAP_CONCEAL 상수.
버전 3.13에서 추가: MAP_32BIT, MAP_HASSEMAPHORE, MAP_JIT, MAP_NOCACHE, MAP_NOEXTEND, MAP_NORESERVE, MAP_RESILIENT_CODESIGN, MAP_RESILIENT_MEDIA, MAP_TPRO, MAP_TRANSLATED_ALLOW_EXECUTE, MAP_UNIX03 상수.