http://www.freak-search.com/en/thread/790540/tzset_locks_in_linux_after_fork
"mike
10.08.2010 - 01:43
I've got an issue with an application I've developed that uses a
combination of threads (pthreads) and fork()'d processes.
In short, my parent process has a handful of threads that run to
perform various tasks; when a new request comes into the parent
process, it forks off a new child to handle the request; one of the
first things the child does is initiate a library that has a date
class that calls tzset().
My parent process also logs the requests from a thread, which writes
the date to the log using localtime_r(), which also calls tzset().
The problem, is that one of out every x child processes fork()'d
simply hangs at a lock in tzset() when the library is initialized.
I've reproduced this by creating a very simple test program, that
simply calls tzset() over and over from a thread, while it forks, and
then calls tzset() in the child process- I can get it to hang almost
immediately.
and this only seems to happen on my Linux machines (CentO/S 5.5)- my
FreeBSD (8.0) runs my test program file, without any locks.
So my question is: if I fork() while tzset() is holding a lock in the
parent process, will the lock get copied to the child process locked?
Is this a known result? is
here a way around this?
Test program, which is just a super simple version of what I see in my
real app, and gdb output below, which is when I attached to a child
process that had hung.
Mike
#include <stdlib.h> #include <stdio.h> #include <time.h> #include <unistd.h> #include <signal.h> #include <pthread.h>
static void* setter(void*) { while(1) { tzset(); }
return NULL; }
int main(void) { pthread_t thread; pthread_create(&thread, NULL, &setter, NULL);
signal(SIGCHLD, SIG_IGN);
while(1) { switch( fork() ) { case 0: { fprintf(stderr, "CHILD >> tzset()\n"); tzset(); exit(1); } break;
case -1: { fprintf(stderr, ">> failed to fork() \n"); } break;
default: { ; } }
usleep(1000); }
return 0; } |
Reading symbols from /home/mike/thr/test...done.
Attaching to program: /home/mike/thr/test, process 8397
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols
found)...done.
[Thread debugging using libthread_db enabled]
Loaded symbols for /lib64/libpthread.so.0
Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols
found)...done.
Loaded symbols for /usr/lib64/libstdc++.so.6
Reading symbols from /lib64/libm.so.6...(no debugging symbols
found)...done.
Loaded symbols for /lib64/libm.so.6
Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols
found)...done.
Loaded symbols for /lib64/libgcc_s.so.1
Reading symbols from /lib64/libc.so.6...(no debugging symbols
found)...done.
Loaded symbols for /lib64/libc.so.6
Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging
symbols found)...done.
Loaded symbols for /lib64/ld-linux-x86-64.so.2
0x0000003512cdfade in __lll_lock_wait_private () from /lib64/libc.so.6
(gdb) bt
#0 0x0000003512cdfade in __lll_lock_wait_private () from /lib64/
libc.so.6
#1 0x0000003512c8d20b in _L_lock_1920 () from /lib64/libc.so.6
#2 0x0000003512c8d0f1 in tzset () from /lib64/libc.so.6
#3 0x0000000000400811 in main () at test.cpp:32
(gdb) info threads
* 1 Thread 0x2ab3c2e9dbb0 (LWP 8397) 0x0000003512cdfade in
__lll_lock_wait_private () from /lib64/libc.so.6
'C, C++' 카테고리의 다른 글
[beautiful code] A Regular Expression Matcher : Brian Kernighan & Rob Pike (0) | 2011.07.28 |
---|---|
get glibc version (0) | 2011.07.16 |
QtConcurrent : MapReduce 모델에 대한 Qt의 대안 (0) | 2011.01.08 |
const pointer & calling functions (0) | 2010.09.09 |
c++ std exception example (0) | 2010.05.04 |