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 );
- It can indicate the file is already locked when
LOCK_NB
is used.errno == EWOULDBLOCK
if that's the case. But you didn't useLOCK_NB
.