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>