简体   繁体   中英

How do I prevent any other process from writing to a file while reading from it in C?

Background

In my C program, I am reading from a file line by line.

FILE *file = fopen("config.txt", "r");

if (file)
{
    char *line;
    size_t length;
    size_t read;
    int test_case_number = 0;

    while ((read = getline(&line, &length, file)) != -1)
    {
        printf("%s", line);
    }
}
else
{
    fputs("The provided <PATH_TO_CONFIG FILE> does not exist.\n\n");
    exit(1);
}

Issue

However, while I am reading this file, I want to prevent any other process from writing to config.txt while its being read. How can I do this?

In Linux, you can use flock() (focus by me):

Apply or remove an advisory lock on an open file.

LOCK_EX Place an exclusive lock . Only one process may hold an exclusive lock for a given file at a given time.

However, you'd need to open your file with open() , instead of fopen() .

Question with abstract example: flock(): removing locked file without race condition? Or check this example .

IMPORTANT: As @JonathanLeffler commented "Note the term "advisory lock" — that means that if the writing process does not test for the lock, it will be able to write. On POSIX-like systems, you can use flock() or lockf() or fcntl() locking on the file descriptor via fileno(fp) ".

If you have to "defend" against your own processes or "well behaved" processes, then you want to use flock :

   fp = fopen(fileName, fileMode);
   if (fp != NULL) {
       flock(fileno(fp), LOCK_EX);
       ...
       fclose(fp); fp = NULL;
   }

But those locks are advisory only, that is, any other process can choose to ignore them . Or not bother checking. I've just tried creating a file, opening it and locking with LOCK_EX, then sleeping for 60 seconds. During that time, another process was free to do whatever it wanted to the file (Linux, Ubuntu 18.04-LTS).

But if you need mandatory locking, that's not something that is available on all platforms since the kernel has to cooperate. Here you will find a description and example on how the limited mandatory lock support in Linux can be used.

On the other hand, in Windows this is automatic:

Windows defaults to automatic, mandatory file locking. UNIXes default to manual, cooperative file locking. In both cases, the defaults can be overridden, but in both cases they usually aren't. ( source ).

A workaround can be to temporarily rename the file being worked on to a unique name, possibly creating an empty file with the old name in its place, then renaming it back once you've done; or copying the file as above, leaving a copy for other programs to read. Write denial can also be achieved by changing the file permissions. These solutions require to handle some edge cases, eg where your process crashes or the machine hangs before setting things back as they were.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM