ZetCode

Python os.plock Function

Last modified April 11, 2025

This comprehensive guide explores Python's os.plock function, which controls process locking on Unix systems. We'll cover lock types, privilege requirements, and practical memory management examples.

Basic Definitions

The os.plock function locks process segments into memory, preventing swapping. It's available on Unix systems and requires root privileges for most operations.

Key parameter: op (lock operation type). Common values: PLOCK_PGIN, PLOCK_PGOUT, PLOCK_SHLOCK, PLOCK_EXLOCK. Returns None on success.

Locking Process Text Segment

This example demonstrates locking the text segment (executable code) of a process into memory. This prevents swapping of program instructions.

lock_text_segment.py
import os

try:
    # Lock text segment (executable code) into memory
    os.plock(os.PLOCK_TEXT)
    print("Process text segment locked in memory")
except AttributeError:
    print("os.plock not available on this platform")
except PermissionError:
    print("Requires root privileges to lock memory")

This code attempts to lock the executable portion of the process in RAM. The operation requires root privileges and is Unix-specific.

Note that PLOCK_TEXT is not available on all Unix variants. The operation may fail even with proper privileges on some systems.

Locking Process Data Segment

This example shows how to lock the data segment (variables, heap) into memory. This prevents swapping of process data structures.

lock_data_segment.py
import os

try:
    # Lock data segment (variables, heap) into memory
    os.plock(os.PLOCK_DATA)
    print("Process data segment locked in memory")
    
    # Allocate some memory that will stay in RAM
    large_list = [0] * 1000000
except AttributeError:
    print("os.plock not available on this platform")
except PermissionError:
    print("Requires root privileges to lock memory")

After locking the data segment, any allocated memory (like large_list) will remain in physical RAM. This is useful for real-time applications.

Be cautious with memory locking as it reduces available RAM for other processes and the system cache.

Unlocking Process Segments

This example demonstrates unlocking previously locked process segments. Memory locking should be temporary for critical sections only.

unlock_segments.py
import os

try:
    # Lock both text and data segments
    os.plock(os.PLOCK_TEXT | os.PLOCK_DATA)
    print("Process segments locked in memory")
    
    # Critical section code here
    
    # Unlock segments when done
    os.plock(os.PLOCK_UNLOCK)
    print("Process segments unlocked")
except AttributeError:
    print("os.plock not available on this platform")
except PermissionError:
    print("Requires root privileges to lock memory")

The example locks memory for a critical section, then unlocks it. PLOCK_UNLOCK releases all locks held by the process.

Always unlock memory when done to avoid system resource exhaustion. Unnecessary locking can degrade overall system performance.

Shared Memory Locking

This example shows shared memory locking between processes. PLOCK_SHLOCK provides a shared advisory lock on memory segments.

shared_memory_lock.py
import os
import sys

try:
    if len(sys.argv) > 1 and sys.argv[1] == "exclusive":
        # Request exclusive lock
        os.plock(os.PLOCK_EXLOCK)
        print("Exclusive memory lock acquired")
    else:
        # Request shared lock
        os.plock(os.PLOCK_SHLOCK)
        print("Shared memory lock acquired")
        
    # Process shared memory operations here
    input("Press Enter to release lock...")
    
    os.plock(os.PLOCK_UNLOCK)
except AttributeError:
    print("os.plock not available on this platform")
except PermissionError:
    print("Requires root privileges to lock memory")

The script accepts a command-line argument to choose between shared and exclusive locking modes. Shared locks allow concurrent readers.

Exclusive locks (PLOCK_EXLOCK) block other processes from acquiring any lock on the same memory segments.

Preventing Page Outs

PLOCK_PGIN prevents pages from being paged out, while PLOCK_PGOUT forces pages out. This example demonstrates both operations.

page_control.py
import os
import time

try:
    # Prevent pages from being paged out
    os.plock(os.PLOCK_PGIN)
    print("Pages will remain in memory")
    
    # Allocate some memory
    data = bytearray(1024 * 1024)  # 1MB
    
    # Keep pages in memory for 10 seconds
    time.sleep(10)
    
    # Allow pages to be paged out
    os.plock(os.PLOCK_PGOUT)
    print("Pages may now be paged out")
except AttributeError:
    print("os.plock not available on this platform")
except PermissionError:
    print("Requires root privileges to control paging")

The example first prevents memory pages from being swapped out, allocates memory, then allows swapping after a delay.

PLOCK_PGIN/PGOUT provide more granular control than segment locking but still require root privileges on most systems.

Checking Lock Support

This example demonstrates how to check for plock support and available operations before attempting to use them.

check_support.py
import os
import sys

def check_plock_support():
    if not hasattr(os, 'plock'):
        print("os.plock not supported on this platform")
        return False
    
    required_constants = ['PLOCK_TEXT', 'PLOCK_DATA', 'PLOCK_SHLOCK']
    missing = [c for c in required_constants if not hasattr(os, c)]
    
    if missing:
        print(f"Missing required constants: {', '.join(missing)}")
        return False
    
    return True

if check_plock_support():
    print("os.plock is supported with basic operations")
    try:
        os.plock(os.PLOCK_TEXT)
        print("Successfully locked text segment")
        os.plock(os.PLOCK_UNLOCK)
    except PermissionError:
        print("Insufficient privileges to lock memory")
else:
    print("os.plock functionality not fully available")

The function checks for plock availability and required constants before attempting to use them. This prevents AttributeError exceptions.

Even with support checks, always handle PermissionError as memory locking typically requires elevated privileges.

Real-time Application Example

This example shows a simplified real-time application using memory locking to ensure consistent performance by preventing swapping.

realtime_application.py
import os
import time

def realtime_task():
    # Critical real-time processing
    for i in range(10):
        print(f"Processing cycle {i}")
        time.sleep(0.1)

try:
    # Lock text and data segments
    os.plock(os.PLOCK_TEXT | os.PLOCK_DATA)
    print("Memory locked for real-time operation")
    
    # Allocate working memory
    buffer = bytearray(1024 * 512)  # 512KB working buffer
    
    # Execute real-time task
    realtime_task()
    
    # Release locks
    os.plock(os.PLOCK_UNLOCK)
    print("Memory locks released")
except (AttributeError, PermissionError) as e:
    print(f"Warning: Could not lock memory ({e})")
    print("Running without memory locks (may experience swapping delays)")
    realtime_task()

The example locks memory for a time-sensitive task, with fallback to unlocked operation if privileges are insufficient.

This pattern is common in real-time systems where consistent timing is more important than absolute performance.

Security Considerations

Best Practices

Source References

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Python tutorials.