Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 18 Jul 2001 14:12:43 -0400
From:      "Louis-Philippe Gagnon" <louisphilippe@macadamian.com>
To:        <freebsd-hackers@FreeBSD.ORG>
Cc:        "Stephane Lussier" <stephane@macadamian.com>
Subject:   flock/pthread bug?
Message-ID:  <1f9c01c10fb5$3d4ba770$2964a8c0@macadamian.com>

next in thread | raw e-mail | index | archive | help
Hi,

I've been looking for a way to get inter-process synchronization between multithreaded processes. (I need synchronized access to
an area of shared memory between multiple instances of the same process)

Since I was using SysV shared memory, I had first thought of using SysV semaphores for synchronization; however, the functions
semop, semctl (etc) don't seem to be pthread-aware, so that if a semop() call blocks, the entire process is blocked instead of
only the calling thread.

I then looked at the pthread mutexes, but it looks like the FreeBSD implementation doesn't support PTHREAD_PROCESS_SHARED (at
least in 4.3-release; has this changed in -stable or -current?)

Then I found out about the flock() function; the man page mentions a different implementation for threaded and non-threaded
libraries, so I though this would work with pthreads.

This does not appear to be the case. If one program locks a file with flock(LOCK_EX), the next program that tries to lock will be
suspended completely, instead of only the calling thread.

Given this program :

#include <pthread.h>

#include <fcntl.h>
#include <stdio.h>
#include <sys/file.h>

void *printf_thread(void *p)
{
    while(1)
        printf("#");
}

void main(void)
{
    pthread_t t;
    int fd;

    fd = open("lockfile",O_WRONLY|O_CREAT, 0666);
    pthread_create(&t,NULL,printf_thread,NULL);
    flock(fd,LOCK_EX);
    pthread_join(t,NULL);
}

(program opens a file, launches a thread (which calls printf() endlessly), locks the file and waits for ^C)

The first instance launched will print an infinity of #'s from its printf_thread
The second instance (launced from the sae directory, to use the same lock file) will not print anything until the first intance is
killed. Since the printf_thread is launched before the flock() call, I expected it to keep running while the main thread blocks;
instead, both threads apear to be blocked.

(I tried on Linux (RH6.1), the program behaves as I expected)

I tried another test before this one (don't have the source anymore, I overwrote the same file), which used only one instance of
the program, with 2 threads trying to lock the file
I expected something like this :
thread 1 locks the file
thread 2 tries to lock the file, blocks
thread 1 unlocks the file
thread 2 gets file lock and unblocks

Instead I got
thread 1 locks the file
thread 2 tries to lock the file, whole process blocks
(thread 1 is blocked, can't unlock the file : deadlock)

So :
-Is flock() supposed to block the whole process?
-Is my test program wrong?
-Does this look like a bug in libc_r?
-Is there a better (working) way of getting interprocess synchronization in multithreaded programs?

Thanks.

Louis-Philippe Gagnon

ps. should I submit problem reports immediately in cases like this, or wait for people's opinions first?




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1f9c01c10fb5$3d4ba770$2964a8c0>