Ei vielä käännetty
Tätä sivua ei ole vielä käännetty suomeksi, joten se näytetään englanniksi. Auta kääntämään
fcntl Module¶
The fcntl module wraps three Unix system calls, fcntl(), ioctl() and flock(), plus lockf(), which is fcntl()'s record locking behind a simpler signature. Each is one call into the kernel, and the bounds below count that call as constant: what the kernel does with a lock table or a driver's ioctl handler is not priced. The only work Python adds is copying a bytes-like argument through a fixed 1024-byte buffer: in before the call, and out afterwards into a new bytes object of the same length or, for a buffer ioctl() mutates, back into that buffer. A writable buffer longer than that is handed to the kernel as it is by a mutating ioctl(). Any other argument over 1024 bytes raises ValueError through Python 3.14; from Python 3.15 it is copied into the new bytes object directly, so the copy stays O(n) with no cap.
Complexity Reference¶
| Operation | Time | Space | Notes |
|---|---|---|---|
fcntl.fcntl(fd, cmd, arg=0) with an integer arg |
O(1) | O(1) | One system call; returns its integer result |
fcntl.fcntl(fd, cmd, arg) with a bytes or str arg |
O(n) | O(n) | n = length of arg in bytes, UTF-8 encoded for a str; through Python 3.14 at most 1024 or ValueError, with no cap from Python 3.15. Copied in, and the result is a new bytes of the same length. Other bytes-like objects such as bytearray are accepted from Python 3.14 |
fcntl.ioctl(fd, request, arg=0) with an integer arg |
O(1) | O(1) | One system call; returns its integer result |
fcntl.ioctl(fd, request, arg) with a read-only bytes-like or str arg, or mutate_flag=False |
O(n) | O(n) | Same copy as fcntl(), and the same 1024-byte cap through Python 3.14 |
fcntl.ioctl(fd, request, buffer, mutate_flag=True) with a writable buffer |
O(n) | O(1) | n = buffer length. Up to 1024 bytes it is copied through the fixed buffer and back; a longer one is handed to the kernel uncopied, so the cap does not apply. The caller's buffer is changed in place and the integer result returned |
fcntl.flock(fd, operation) |
O(1) | O(1) | Locks the open file description, so a second open() of the file contends even in the same process; a system without flock(2) gets lockf()'s process-owned lock instead. Waits for a conflicting lock unless LOCK_NB is set, which raises BlockingIOError instead; the waiting is not work |
fcntl.lockf(fd, cmd, len=0, start=0, whence=0) |
O(1) | O(1) | A byte-range lock through fcntl(), owned by the process: another descriptor in the same process never contends, and closing any descriptor of the file releases it. An exclusive lock needs the file open for writing |
fcntl.LOCK_SH, fcntl.LOCK_EX, fcntl.LOCK_NB, fcntl.LOCK_UN |
O(1) | O(1) | Operation flags for flock() and lockf() |
fcntl.LOCK_MAND, fcntl.LOCK_READ, fcntl.LOCK_WRITE, fcntl.LOCK_RW |
O(1) | O(1) | Linux mandatory-lock flags for flock(); platform-dependent |
fcntl.F_DUPFD, fcntl.F_DUPFD_CLOEXEC, fcntl.F_GETFD, fcntl.F_SETFD, fcntl.F_GETFL, fcntl.F_SETFL, fcntl.FD_CLOEXEC, fcntl.FASYNC |
O(1) | O(1) | Descriptor commands and flag bits for fcntl() |
fcntl.F_GETLK, fcntl.F_SETLK, fcntl.F_SETLKW, fcntl.F_GETLK64, fcntl.F_SETLK64, fcntl.F_SETLKW64, fcntl.F_OFD_GETLK, fcntl.F_OFD_SETLK, fcntl.F_OFD_SETLKW, fcntl.F_RDLCK, fcntl.F_WRLCK, fcntl.F_UNLCK, fcntl.F_SHLCK, fcntl.F_EXLCK |
O(1) | O(1) | Record-lock commands and lock types for fcntl(); which exist is platform-dependent |
fcntl.F_GETOWN, fcntl.F_SETOWN, fcntl.F_GETSIG, fcntl.F_SETSIG, fcntl.F_NOTIFY, fcntl.DN_ACCESS, fcntl.DN_MODIFY, fcntl.DN_CREATE, fcntl.DN_DELETE, fcntl.DN_RENAME, fcntl.DN_ATTRIB, fcntl.DN_MULTISHOT, fcntl.F_GETLEASE, fcntl.F_SETLEASE, fcntl.F_GETPIPE_SZ, fcntl.F_SETPIPE_SZ |
O(1) | O(1) | Signal-driven I/O, directory notification, lease and pipe-size commands for fcntl(); platform-dependent |
fcntl.F_ADD_SEALS, fcntl.F_GET_SEALS, fcntl.F_SEAL_SEAL, fcntl.F_SEAL_SHRINK, fcntl.F_SEAL_GROW, fcntl.F_SEAL_WRITE |
O(1) | O(1) | File-sealing commands and seal bits for fcntl(); platform-dependent |
fcntl.F_GETPATH, fcntl.F_NOCACHE, fcntl.F_FULLFSYNC |
O(1) | O(1) | macOS commands for fcntl(); platform-dependent |
fcntl.I_ATMARK, fcntl.I_CANPUT, fcntl.I_CKBAND, fcntl.I_FDINSERT, fcntl.I_FIND, fcntl.I_FLUSH, fcntl.I_FLUSHBAND, fcntl.I_GETBAND, fcntl.I_GETCLTIME, fcntl.I_GETSIG, fcntl.I_GRDOPT, fcntl.I_GWROPT, fcntl.I_LINK, fcntl.I_LIST, fcntl.I_LOOK, fcntl.I_NREAD, fcntl.I_PEEK, fcntl.I_PLINK, fcntl.I_POP, fcntl.I_PUNLINK, fcntl.I_PUSH, fcntl.I_RECVFD, fcntl.I_SENDFD, fcntl.I_SETCLTIME, fcntl.I_SETSIG, fcntl.I_SRDOPT, fcntl.I_STR, fcntl.I_SWROPT, fcntl.I_UNLINK |
O(1) | O(1) | STREAMS requests for ioctl(); platform-dependent |
fcntl.F_DUP2FD, fcntl.F_DUP2FD_CLOEXEC |
O(1) | O(1) | Python 3.11+; FreeBSD commands for fcntl(), platform-dependent |
fcntl.FICLONE, fcntl.FICLONERANGE |
O(1) | O(1) | Python 3.12+; Linux copy-on-write clone requests for ioctl(), platform-dependent |
fcntl.F_GETOWN_EX, fcntl.F_SETOWN_EX, fcntl.F_OWNER_PID, fcntl.F_OWNER_PGRP, fcntl.F_OWNER_TID, fcntl.F_GET_RW_HINT, fcntl.F_SET_RW_HINT, fcntl.F_GET_FILE_RW_HINT, fcntl.F_SET_FILE_RW_HINT, fcntl.RWH_WRITE_LIFE_NOT_SET, fcntl.RWH_WRITE_LIFE_NONE, fcntl.RWH_WRITE_LIFE_SHORT, fcntl.RWH_WRITE_LIFE_MEDIUM, fcntl.RWH_WRITE_LIFE_LONG, fcntl.RWH_WRITE_LIFE_EXTREME, fcntl.F_SEAL_FUTURE_WRITE, fcntl.F_READAHEAD, fcntl.F_ISUNIONSTACK, fcntl.F_KINFO, fcntl.F_RDAHEAD, fcntl.F_CLOSEM, fcntl.F_MAXFD, fcntl.F_GETNOSIGPIPE, fcntl.F_SETNOSIGPIPE |
O(1) | O(1) | Python 3.13+; commands and values for fcntl(), each on the platforms that define it |
fcntl.F_DUPFD_QUERY |
O(1) | O(1) | Python 3.14+; Linux command for fcntl(), platform-dependent |
File Locking and Control¶
File Locking¶
import fcntl
# Open without truncating: the file must not change before the lock is held
with open('data.txt', 'a+') as f:
# Acquire lock - O(1)
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
try:
# Replace the contents while locked; flush so the data lands before the lock goes
f.seek(0)
f.truncate()
f.write('Protected data')
f.flush()
finally:
# Release lock - O(1)
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
Non-blocking Lock¶
import fcntl
# A flock() lock belongs to the open file description, so a second
# open() of the same file contends with the first even in one process
with open('file.txt', 'w') as holder, open('file.txt', 'w') as f:
fcntl.flock(holder.fileno(), fcntl.LOCK_EX)
try:
# Non-blocking exclusive lock - O(1)
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
print("Lock acquired")
except BlockingIOError:
print("File is locked elsewhere")