Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python fcntl 모듈 완벽 정리: 파일 제어와 락킹을 위한 fcntl·ioctl 시스템 호출

Python fcntl 모듈이란?

파일과 입출력(IO)을 세밀하게 제어하려면 fcntl 모듈을 사용해야 합니다. 이 모듈은 유닉스 계열 운영체제의 fcntl()ioctl() 루틴에 대한 파이썬 인터페이스 역할을 하며, 파일 잠금, 파일 디스크립터 조작 등 저수준 파일 제어 작업을 수행할 수 있게 해줍니다.

이 모듈의 모든 메서드는 첫 번째 인수로 정수형 파일 디스크립터 또는 io.IOBase 객체를 받습니다.

모듈을 사용하려면 먼저 다음과 같이 임포트합니다.

import fcntl

fcntl 모듈의 주요 메서드

1. fcntl.fcntl(fd, op[, arg])

파일 디스크립터를 통해 파일에 지정된 연산을 수행합니다. 수행할 연산은 op 매개변수로 정의되며, 세 번째 인수 arg는 선택 사항입니다.

  • arg가 정수형일 때: C 언어의 fcntl() 호출 반환값이 그대로 반환됩니다.

  • arg가 문자열일 때: 이진(binary) 구조체를 의미하며, 버퍼 데이터를 전달하는 용도로 사용됩니다.

  • 함수 호출이 실패하면 IOError(현재는 OSError) 예외가 발생합니다.

2. fcntl.ioctl(fd, op[, arg[, mutate_flag]])

fcntl() 메서드와 기본적으로 동일하지만, 인수 처리 방식이 더 복잡합니다. 인수로 변경 가능한(mutable) 버퍼를 전달할 경우 동작은 mutate_flag 값에 따라 달라집니다.

  • mutate_flag가 True인 경우: 버퍼의 내용이 갱신될 수 있습니다(읽기/쓰기 모두 허용).

  • mutate_flag가 False인 경우: 버퍼는 읽기 전용처럼 동작합니다.

3. fcntl.flock(fd, op)

파일 디스크립터를 사용해 파일에 락(lock) 연산 op를 적용합니다. 일부 시스템에서는 이 메서드가 내부적으로 fcntl() 방식으로 에뮬레이트(emulate)되어 실행됩니다.

4. fcntl.lockf(fd, operation[, length[, start[, whence]]])

파일 락킹 호출을 감싸는 래퍼(wrapper) 역할을 하는 메서드입니다. operation 인수를 통해 파일을 잠그거나 잠금을 해제할 수 있으며, 다음과 같은 상수 값을 사용합니다.

  • LOCK_UN — 파일 잠금 해제

  • LOCK_SH — 공유 잠금(Shared Lock): 여러 프로세스가 동시에 읽기 가능

  • LOCK_EX — 배타적 잠금(Exclusive Lock): 한 프로세스만 접근 가능

예제 코드

아래 예제는 flock()으로 배타적 잠금을 걸어 카운터 파일을 안전하게 갱신하는 코드입니다. 실제 환경에서는 여러 프로세스가 동시에 실행되더라도 잠금 덕분에 카운트 값이 손실 없이 증가합니다.

import fcntl, os, time

counter_file = 'my_counter.txt'
if not os.path.exists(counter_file):
   counter_file = open('my_counter.txt', 'w')
   counter_file.write('0')  # 시작값으로 0 저장
   counter_file.close()

for i in range(15):
   counter_file = open('my_counter.txt', 'r+')
   fcntl.flock(counter_file.fileno(), fcntl.LOCK_EX)
   count = int(counter_file.readline()) + 1
   counter_file.seek(0)
   counter_file.write(str(count))
   counter_file.close()
   print('Process ID: ' + str(os.getpid()) + ', Count: ' + str(count))
   time.sleep(0.2)

실행 결과

$ python3 example.py
Process ID: 12698, Count: 1
Process ID: 12698, Count: 2
Process ID: 12698, Count: 3
Process ID: 12698, Count: 4
Process ID: 12698, Count: 5
Process ID: 12698, Count: 6
Process ID: 12698, Count: 7
Process ID: 12698, Count: 8
Process ID: 12698, Count: 9
Process ID: 12698, Count: 10
Process ID: 12698, Count: 11
Process ID: 12698, Count: 12
Process ID: 12698, Count: 13
Process ID: 12698, Count: 14
Process ID: 12698, Count: 15
$
cat my_counter.txt
15
$

마무리

fcntl 모듈은 유닉스 계열 시스템에서 파일 잠금과 저수준 파일 제어를 담당하는 핵심 도구입니다. 특히 여러 프로세스가 하나의 파일에 동시에 접근하는 상황에서 데이터 무결성을 보장해야 할 때 flock()이나 lockf()를 활용하면 경쟁 상태(race condition)를 효과적으로 방지할 수 있습니다. 단, Windows에서는 지원되지 않으므로 플랫폼 호환성을 고려한 설계가 필요합니다.