Skip to content

Instantly share code, notes, and snippets.

@carlohamalainen
Created June 6, 2024 04:34
Show Gist options
  • Save carlohamalainen/941a10eabc435d99ca3ad27d4620f9c0 to your computer and use it in GitHub Desktop.
Save carlohamalainen/941a10eabc435d99ca3ad27d4620f9c0 to your computer and use it in GitHub Desktop.
file locking
/*
Tested on MacOS and Linux Debian.
USE_LOCK = 1:
❯ gcc exclusive.c -o exclusive && parallel -j 1000 ./exclusive -- {1..1000} | sort | uniq -c
1000 10000
USE_LOCK = 0:
❯ gcc exclusive.c -o exclusive && parallel -j 1000 ./exclusive -- {1..1000} | sort | uniq -c
91 0
539 10000
182 4096
188 8192
*/
#include <stdio.h>
#include <sys/file.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#define USE_LOCK 1
void write_data(FILE *file) {
if (file) {
for(int i = 0; i < 10000; i++) {
fprintf(file, "x");
}
fclose(file); // closes the underlying file descriptor too
}
}
void write_with_lock() {
int fd = open("example.txt", O_WRONLY | O_CREAT);
if (fd == -1) {
perror("open");
return;
}
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl");
close(fd);
return;
}
FILE *file = fdopen(fd, "w");
write_data(file);
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
}
void read_data(FILE *file) {
long bytes = 0;
int ch;
while ((ch = fgetc(file)) != EOF) {
bytes++;
}
fclose(file);
printf("%ld\n", bytes);
}
void read_with_lock() {
int fd = open("example.txt", O_RDONLY);
if (fd == -1) {
perror("open");
return;
}
struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
if (fcntl(fd, F_SETLKW, &lock) == -1) {
perror("fcntl");
close(fd);
return;
}
FILE *file = fdopen(fd, "r");
read_data(file);
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
}
int main() {
#if USE_LOCK
write_with_lock();
#else
FILE *file = fopen("example.txt", "w");
write_data(file);
#endif
#if USE_LOCK
read_with_lock();
#else
file = fopen("example.txt", "r");
read_data(file);
#endif
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment