Click on the above“Embedded and Linux Matters” Select“Pin/Star Public Account”Benefits and resources delivered promptly
Hello everyone, I am the Information Guy~
As the project gradually comes to a close, I am summarizing some technical points of Linux application development. Since my project is a multi-process system, it involves issues of resource sharing among processes. The file locking (File Locking) summarized in this article is key to solving these problems!
1. Three Major Issues in Multi-Process Development
First, let me introduce the three issues I encountered:
1. Log System Line Interleaving Issue
When multiple processes write data to the same log file simultaneously, the kernel’s I/O buffer may cause log lines to interleave. For example:
Process A writes: 2025-05-01 10:00:01 [A] Start task...
Process B writes: 2025-05-01 10:00:02 [B] Error: file not found
Process A writes: 2025-05-01 10:00:03 [A] Task completed.
The actual log may become:
2025-05-01 10:00:01 [A] Start task...2023-10-01 10:00:02 [B] Error: file not found
2025-05-01 10:00:03 [A] Task completed.
This format disorder makes the log very difficult to read and unusable for troubleshooting.
2. Configuration File Update Causing Corruption
If two processes modify the configuration file (e.g., <span>config.json</span>):• Process A writes the first half of the content, and then Process B preempts the write permission.
• Process B overwrites part of Process A’s content, resulting in incomplete file content.
Configuration file data corruption can lead to severe service crashes.
3. Duplicate Startup of Singleton Process
Daemon processes (e.g., <span>daemon</span>) typically require only one instance to run. If not locked, when a user mistakenly restarts the process, it leads to resource contention (e.g., port occupation), ultimately causing the service to become unavailable.
2. File Locking is Here
File locking mainly coordinates concurrent access to files by multiple processes through kernel mechanisms, solving the following issues:• Mutual exclusion: Only one process is allowed to modify the file at any given time.
• Data consistency: Ensures the integrity of file content and the atomicity of operations.
• Process synchronization: Avoids unpredictable behavior caused by resource contention.
However, there are typically two types of file locks in Linux systems:
- Advisory Lock: Relies on processes to actively comply with lock rules (commonly used).
- Mandatory Lock: Enforced by the kernel to restrict read/write (requires special configuration).
Mandatory locks are relatively inefficient, so advisory locks are usually used. The main APIs used are:
<span>flock(): Locks the entire file (based on file descriptor).</span><span>fcntl(): Supports locking a specific region of the file (more granular).</span><span>lockf(): A wrapper around </span><span>fcntl()</span> to simplify file lock operations.First Example: Multi-Process Safe Logging
Goal: Ensure multiple processes write logs in order to avoid line interleaving.Code implementation:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <time.h>
void write_log(const char *message) {
int fd = open("app.log", O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd == -1) {
perror("open log failed");
exit(1);
}
// Acquire exclusive lock (blocking until the lock is obtained)
struct flock lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
.l_start = 0,
.l_len = 0 // Lock the entire file
};
fcntl(fd, F_SETLKW, &lock);
// Write log (with timestamp)
time_t now = time(NULL);
char buffer[256];
snprintf(buffer, sizeof(buffer), "[%ld] %s\n", now, message);
write(fd, buffer, strlen(buffer));
// Release lock
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
}
int main() {
// Simulate multi-process writing (compile and start multiple processes for testing)
write_log("Process started");
sleep(1); // Simulate business logic time consumption
write_log("Process finished");
return 0;
}
Before each log write, an exclusive lock is obtained using <span>F_WRLCK</span>, ensuring atomicity. <span>F_SETLKW</span> will block the process until the lock is released, which actually resembles read/write locks in thread synchronization.
Second Example: Singleton Process Lock File Implementation
Goal: Prevent duplicate startup by using lock file <span>/var/run/myapp.pid</span>. Code implementation:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <errno.h>
void enforce_singleton() {
const char *lockfile = "/var/run/myapp.pid";
int fd = open(lockfile, O_WRONLY | O_CREAT, 0644);
if (fd == -1) {
perror("open lockfile failed");
exit(1);
}
// Attempt to acquire advisory lock (non-blocking)
struct flock lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
.l_start = 0,
.l_len = 0
};
if (fcntl(fd, F_SETLK, &lock) == -1) {
if (errno == EAGAIN || errno == EACCES) {
fprintf(stderr, "Error: Another instance is already running.\n");
exit(1);
} else {
perror("fcntl failed");
exit(1);
}
}
// Write current process ID
char pid_str[16];
snprintf(pid_str, sizeof(pid_str), "%d\n", getpid());
ftruncate(fd, 0); // Clear file content
write(fd, pid_str, strlen(pid_str));
}
int main() {
enforce_singleton();
printf("Service started. PID: %d\n", getpid());
while (1) {
sleep(60); // Simulate daemon process logic
}
return 0;
}
By attempting to acquire an exclusive lock on the lock file at startup, if it fails, the process exits. The lock file content is the process PID, which aids in troubleshooting, similar to the singleton pattern in design patterns.
You can also use the <span>lslocks</span> command to view current file locks in the system. It is worth noting the granularity of locks (global lock vs. regional lock) and the risk of deadlocks.
end
Previous Recommendations
Essential Classic Books for Embedded Linux
Recommended Learning Path for Embedded Systems
A reader’s clear and logical question
Successful transition from mechanical engineering to embedded systems
A reader’s experience of landing a job in audio and video direction during the autumn recruitment


Scan to add me on WeChat
Join the technical exchange group


Share

Collect

Like

Looking