Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

fcntl และ ioctl System Calls ใน Python

โมดูล fcntl เป็น Interface ไปยัง fcntl() และ ioctl() System Calls ของ UNIX สำหรับควบคุม File Descriptor และ I/O

import fcntl


เมธอดหลัก

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

ทำ Operation บน File Descriptor

  • fd: File Descriptor (int หรือ io.IOBase)
  • op: Operation Code (F_GETFL, F_SETFL, F_GETFD, F_SETFD, F_GETLK, F_SETLK, F_SETLKW)
  • arg: Optional Argument (int หรือ bytes)

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

เหมือน fcntl แต่ Argument Handling ซับซ้อนกว่า รองรับ Mutable Buffer

fcntl.flock(fd, op)

File Locking แบบง่าย (BSD Style)

  • LOCK_SH - Shared Lock (อ่านพร้อมกันได้)
  • LOCK_EX - Exclusive Lock (เขียน/อ่าน独占)
  • LOCK_UN - Unlock
  • LOCK_NB - Non-blocking (รวมกับ Flag อื่น)

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

Wrapper สำหรับ Locking (POSIX Style) รองรับ Lock บางส่วนของไฟล์


ตัวอย่าง: File Locking เพื่อ Counter แบบ Thread-Safe

import fcntl, os, time

counter_file = 'my_counter.txt'

# สร้างไฟล์เริ่มต้น
if not os.path.exists(counter_file):
    with open(counter_file, 'w') as f:
        f.write('0')

for i in range(15):
    with open(counter_file, 'r+') as f:
        fcntl.flock(f.fileno(), fcntl.LOCK_EX)  # Exclusive Lock
        
        count = int(f.readline()) + 1
        f.seek(0)
        f.write(str(count))
        f.truncate()
        
        fcntl.flock(f.fileno(), fcntl.LOCK_UN)  # Unlock
        
        print(f'PID: {os.getpid()}, Count: {count}')
        time.sleep(0.2)

ผลลัพธ์

PID: 12698, Count: 1
PID: 12698, Count: 2
...
PID: 12698, Count: 15
$ cat my_counter.txt
15

กรณีใช้งานจริง

  • PID File Locking (ป้องกันรันซ้ำ)
  • Config File Atomic Update
  • Log Rotation Coordination
  • Inter-process Synchronization

ข้อควรระวัง

  • Lock เป็น Advisory (Process ต้องร่วมมือกัน Lock/Unlock)
  • Network File Systems (NFS) อาจไม่รองรับ Locking ได้เต็มที่
  • ใช้ with Statement เพื่อให้ Unlock อัตโนมัติ