Home > Back-end >  Why flock() in fork() double blocks the same file with different descriptors?
Why flock() in fork() double blocks the same file with different descriptors?

Time:12-23

When I run my code:

int i = fork();

if (!i){
    int id = open("shared.txt", 0600 | O_WRONLY);
    if(flock(id, LOCK_EX) == 0)
        printf("child\n");
    close(id);
}
else {
    int id = open("shared.txt", 0600 | O_WRONLY);
    if(flock(id, LOCK_EX) == 0)
        printf("parent\n");
    close(id);
}

wait(NULL);

I expect that one process will block my file and the other process will not send my a message, because flock() returns -1. But either first and second flock() works with different file descriptors.

CodePudding user response:

I expect that one process will block my file and the other process will not send my a message

No, not at all.

Let's say one of the processes locks the file and the other tries to lock it. flock doesn't return. flock blocks until the file becomes unlocked. The process with the lock will output its message and exit, which releases the lock. The other process will now unblock, output its message and exit. Both processes will always output their messages (eventually).

There is a flag that will cause flock to return immediately if the file is locked: LOCK_NB. But even if you used LOCK_NB, this wouldn't guarantee that only one of the processes would output a message.

Let's say one of the processes locks the file, prints its message and exits before the other process even attempts to lock the file. Easily possible with the program you provided. The other process will have no problem obtaining a lock and thus output its message and exit. It's possible for both processes to output their messages.

flock() returns -1

This does not indicate that the file is already locked; this indicates something went wrong.[1] Perhaps the open failed, so you provided an invalid file descriptor to flock. Both open and flock set errno on error, which you output using perror.

int fd = open( ... );
if ( fd == -1 ) {
   // Error!
   perror( "open" );
   exit( 1 );
}

if ( flock( fd, LOCK_EX ) == -1 )
   // Error!
   perror( "flock" );
   exit( 1 );
}

...

close( fd );

  1. It can indicate the file is already locked when LOCK_NB is used. errno == EWOULDBLOCK if that's the case. But you didn't use LOCK_NB.
  • Related