'thread-safe'에 해당되는 글 1건

  1. 2011.07.12 tzset() locks in Linux after fork()
C, C++2011. 7. 12. 00:10

 

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

Posted by 어쩌다보니 Jay Two

댓글을 달아 주세요