flock(): removing locked file without race condition?

后端 未结 3 719
情深已故
情深已故 2020-12-01 12:04

I\'m using flock() for inter-process named mutexes (i.e. some process can decide to hold a lock on \"some_name\", which is implemented by locking a file named \"some_name\"

3条回答
  •  余生分开走
    2020-12-01 12:55

    1. In Unix it is possible to delete a file while it is opened - the inode will be kept until all processes have ended that have it in their file descriptor list
    2. In Unix it is possible to check that a file has been removed from all directories by checking the link count as it becomes zero

    So instead of comparing the ino-value of the old/new file paths you can simply check the nlink count on the file that is already open. It assumes that it is just an ephemeral lock file and not a real mutex resource or device.

    lockfile = "/tmp/some_name.lock";
    
    for(int attempt; attempt < timeout; ++attempt) {
        int fd = open(lockfile, O_CREAT, 0444);
        int done = flock(fd, LOCK_EX | LOCK_NB);
        if (done != 0) { 
            close(fd);
            sleep(1);     // lock held by another proc
            continue;
        }
        struct stat st0;
        fstat(fd, &st0);
        if(st0.st_nlink == 0) {
           close(fd);     // lockfile deleted, create a new one
           continue;
        }
        do_something();
        unlink(lockfile); // nlink :=0 before releasing the lock
        flock(fd, LOCK_UN);
        close(fd);        // release the ino if no other proc 
        return true;
    }
    return false;
    

提交回复
热议问题