LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to lock files using fcntl() and to work between threads of the same process (https://www.linuxquestions.org/questions/programming-9/how-to-lock-files-using-fcntl-and-to-work-between-threads-of-the-same-process-596066/)

mistretzu 10-31-2007 08:04 AM

How to lock files using fcntl() and to work between threads of the same process
 
I need to look a file and for this I'm using fcntl() function like in the sample bellow.
fcntl() locks are taken into consideration only by other process.

Code:

#include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <unistd.h>
   
    int main(int argc, char *argv[])
    {
            /* l_type  l_whence  l_start  l_len  l_pid  */
            struct flock fl = { F_WRLCK, SEEK_SET, 0,      0,    0 };
            int fd;
   
        fl.l_pid = getpid();
   
            if (argc > 1)
                    fl.l_type = F_RDLCK;
   
            if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
                    perror("open");
                    exit(1);
            }
   
            printf("Press <RETURN> to try to get lock: ");
            getchar();
            printf("Trying to get lock...");
   
            if (fcntl(fd, F_SETLKW, &fl) == -1) {
                    perror("fcntl");
                    exit(1);
            }
   
            printf("got lock\n");
            printf("Press <RETURN> to release lock: ");
            getchar();
   
            fl.l_type = F_UNLCK;  /* set to unlock same region */
   
            if (fcntl(fd, F_SETLK, &fl) == -1) {
                    perror("fcntl");
                    exit(1);
            }
   
            printf("Unlocked.\n");
   
            close(fd);
    }

If I acquire a exclusive lock on a file from thread A, thread B will also succeed in obtaining an exclusive lock on the same file.
How can I make thread B to detect that the specified file is already locked?

vadiml 10-31-2007 08:38 AM

Did you try to open a new file handle (either by opening the same file or by using "dup()" syscall in the second thread?

mistretzu 10-31-2007 09:19 AM

All new handles are created using open().

Wim Sturkenboom 11-01-2007 01:03 AM

Have you considered the use of mutexes. See man pthread_mutex_init
If necessary, you can combine it with a lockfile.

mistretzu 11-01-2007 04:25 AM

After some more thinking I got to the conclusion that combining mutexes and lock files are the best way to do it.

ta0kira 11-01-2007 07:07 AM

File locks aren't mandatory by default. They only work when you check for them first or try to set one where it isn't allowed, or at least that's how your program should look look at it. Rather than try to set it and let it fail in the other threads, you should check for the lock's existence first and then wait if it exists. Unlike interprocess locks you can't just use the wait flag; you'd have to create your own spin-lock.
ta0kira

EDIT: You can make locks mandatory by mounting with the "mand" mount option and setting g-x and g+s on the file, but I don't know if that works within the same process. Might still need to do what I advised above, or maybe use separate file descriptors for each thread. You shouldn't count on the file being set up for mandatory locks, though. Mandatory locks seem like an administrator's tool rather than a programmer's.

orgcandman 11-05-2007 12:45 PM

for multi-threaded access to a file, it is best to use an ADT that contains a reference to the file handle, and a mutex lock that you pass around, or have a file writing thread which other threads ask to write to the file for them. Each carries it's own advantages and drawbacks.


All times are GMT -5. The time now is 12:42 PM.