In this lesson, you will learn how to prevent two concurrent shell processes from corrupting the same data file by using file-based locking.
The Race Condition Problem
Imagine you have two scripts running at the same time, both trying to append a log entry to data.txt. If Process A reads the file, and before it finishes writing, Process B also reads the file, they might overwrite each other's work. This is called a "race condition." To solve this, we use a "lock file" as a digital "Do Not Disturb" sign.
Implementing File-Based Locking
In a shell environment, the mkdir command is a perfect tool for this because it is atomic. This means the operating system guarantees that if two processes try to create the same directory simultaneously, only one will succeed; the other will receive an error.
We can use this to create a lock:
LOCKDIR="/tmp/my_script.lock"
# Attempt to create the directory (the lock)
if mkdir "$LOCKDIR" 2>/dev/null; then
# Success! We own the lock.
echo "Processing data..."
echo "$(date) - Log entry" >> data.txt
# Release the lock
rmdir "$LOCKDIR"
else
# Failed! Another process is working.
echo "Wait, another process is busy."
fi
Why this works
When a process executes mkdir, the Linux kernel handles the request as an indivisible operation. If Process A succeeds in creating the directory, Process B’s mkdir command will fail because the directory already exists. Process B can then either exit or wait (loop) until the lock is released.
By wrapping your critical section—the code that modifies your shared file—between the creation and removal of this directory, you ensure that only one process interacts with your file at any given moment. This prevents data interleaving and keeps your concurrent processes synchronized without needing complex inter-process communication tools.
Key Takeaway: Use an atomic directory creation (mkdir) as a simple, effective lock to ensure only one process at a time can modify your critical data files.