[TriLUG] Fwd: Why do File IO event seem to be out-of-order in strace?

Igor Partola via TriLUG trilug at trilug.org
Tue Sep 15 13:56:40 EDT 2015


A deadlock is simply a condition where process A is waiting on a resource
locked by process B and process B is waiting on a resource locked by
process A. They are trivially avoided by having every code path lock
resources in the same order.

I really don't think that fork is necessary in this case. After all, you
want a system level lock to work between two unrelated processes the same
way as two forks. fnctl() does not care. I cleaned up your example and put
it here:

https://gist.github.com/ipartola/2b7d6ecc3e6c0fbdb668

Compile it via `gcc -Wall main.c` and run it via `./a.out & ./a.out`. You
will see that only one process writes to the file at once.

You are correct in that fcntl() can lock a byte range. However, there be
dragons, and your program correctly sets fl.l_len to 0 which means "lock
the whole file". Check out http://0pointer.de/blog/projects/locking.html
for some gotchas with file locking in general.

If you want portability and to write slightly less code, lockf() from
unistd.h might be a better choice for you:

lockf(fd, F_LOCK, 0); // lock
lockf(fd, F_ULOCK, 0); // unlock

I am not sure if this helps you in any way with your original problem, but
this test program should work fine for you.

Igor

On Tue, Sep 15, 2015 at 1:29 PM, Scott Lambdin via TriLUG <trilug at trilug.org
> wrote:

> Hi -
>
> Just letting you know that I found out the forks are required for the test
> program.  Each process can only lock one byte range, in order to avoid
> something called "Dreadlocks"
>
> --Scott
>
> ---------- Forwarded message ----------
> From: Igor Partola via TriLUG <trilug at trilug.org>
> Date: Tue, Sep 8, 2015 at 4:33 PM
> Subject: Re: [TriLUG] Why do File IO event seem to be out-of-order in
> strace?
> To: Triangle Linux Users Group General Discussion <trilug at trilug.org>
>
>
> Looks to me like you are doing fork() incorrectly:
>
>  if(childPID >= 0) // fork was successful
>     {
>         if(childPID == 0) // child process
>         {
>
> This code after the above statement will run for both parent and child.
> Since you are doing this in a loop the second process you fork will inherit
> the parent's lock.
>
> The correct way to write this would be like so:
>
> childPID = fork();
>
> if (childPID < 0) {
>     puts("Could not fork!");
>     abort(1);
> }
>
> if (childPID == 0) {
>     // Do the lock test.
> }
>
> if (childPID > 0) {
>      // Spawn more children or wait on existing children to exit.
> }
>
>
> For your test, you don't need to fork(). Simply have a program that does
> the locking with a 10 second sleep before unlocking it. Fire off this same
> program twice and watch the second one take longer than 10 seconds while it
> waits for the lock.
>
> Igor
> --
> This message was sent to: Scott Lambdin <lopaki at gmail.com>
> To unsubscribe, send a blank message to trilug-leave at trilug.org from that
> address.
> TriLUG mailing list : http://www.trilug.org/mailman/listinfo/trilug
> Unsubscribe or edit options on the web  :
> http://www.trilug.org/mailman/options/trilug/lopaki%40gmail.com
> Welcome to TriLUG: http://trilug.org/welcome
>
>
>
> --
>
> Eat like you give a damn.  Go vegan.
> --
> This message was sent to: Igor Partola <igor at igorpartola.com>
> To unsubscribe, send a blank message to trilug-leave at trilug.org from that
> address.
> TriLUG mailing list : http://www.trilug.org/mailman/listinfo/trilug
> Unsubscribe or edit options on the web  :
> http://www.trilug.org/mailman/options/trilug/igor%40igorpartola.com
> Welcome to TriLUG: http://trilug.org/welcome
>


More information about the TriLUG mailing list