Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
The fcntl and ioctl System Calls in Python
The fcntl module in Python provides an interface to the fcntl() and ioctl() Unix system calls for file control operations. This module is essential for low-level file descriptor manipulation, file locking, and I/O control operations on Unix-like systems.
All methods in this module take a file descriptor (integer) or io.IOBase object as their first argument. To use this module, import it first:
import fcntl
fcntl.fcntl(fd, op[, arg]) Method
This method performs operations on file descriptors. The op parameter defines the operation, and the optional arg can be an integer or string. When arg is an integer, it returns the C fcntl() call result. When it's a string, it represents a binary structure. Raises IOError on failure.
import fcntl
import os
# Open a file and get its descriptor
with open('test.txt', 'w') as f:
# Get file descriptor flags
flags = fcntl.fcntl(f.fileno(), fcntl.F_GETFL)
print(f"File flags: {flags}")
fcntl.ioctl(fd, op[, arg[, mutate_flag]]) Method
Similar to fcntl() but with more complex argument handling. The mutate_flag parameter controls whether a mutable buffer can be modified. When True, the buffer is mutable; otherwise, it acts as read-only.
fcntl.flock(fd, op) Method
Performs file locking operations using the file descriptor. Common operations include:
LOCK_SH − Shared lock
LOCK_EX − Exclusive lock
LOCK_NB − Non-blocking lock
LOCK_UN − Unlock
fcntl.lockf(fd, operation[, length[, start[, whence]]]) Method
A wrapper around POSIX locking calls with these operations:
LOCK_UN − Unlock the file
LOCK_SH − Shared lock
LOCK_EX − Exclusive lock
File Locking Example
Here's a practical example demonstrating file locking to safely increment a counter ?
import fcntl
import os
import time
counter_file = 'my_counter.txt'
# Create counter file if it doesn't exist
if not os.path.exists(counter_file):
with open('my_counter.txt', 'w') as f:
f.write('0') # Store 0 as starting number
# Increment counter 15 times with file locking
for i in range(15):
with open('my_counter.txt', 'r+') as f:
# Acquire exclusive lock
fcntl.flock(f.fileno(), fcntl.LOCK_EX)
# Read current count and increment
count = int(f.readline()) + 1
# Write new count back to file
f.seek(0)
f.write(str(count))
f.truncate() # Remove any leftover content
print(f'Process ID: {os.getpid()}, Count: {count}')
# File is automatically unlocked when closed
time.sleep(0.2)
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
Key Points
The
fcntlmodule is Unix-specific and not available on WindowsFile locking prevents race conditions in concurrent file access
Always handle
IOErrorexceptions when using fcntl operationsUse context managers (
withstatements) for automatic file closure and lock release
Conclusion
The fcntl module provides essential file control and locking capabilities for system-level programming in Python. Use flock() for file locking and fcntl() for general file descriptor operations to ensure safe concurrent file access.
