Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > tzset() locks in Linux after fork()

Reply
Thread Tools

tzset() locks in Linux after fork()

 
 
mike@fonolo.com
Guest
Posts: n/a
 
      08-09-2010
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 there 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
 
Reply With Quote
 
 
 
 
Jorgen Grahn
Guest
Posts: n/a
 
      08-10-2010
On Mon, 2010-08-09, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I've got an issue with an application I've developed that uses a
> combination of threads (pthreads) and fork()'d processes.

[...]

Others have replied with advice, but in general you're much better off
posting to ... whatever Unix or Linux programming group has the best
audience.

This is comp.lang.c++, your program seems to be a traditional C
program, and the question would be offtopic even in comp.lang.c.

(Your question was interesting and well formulated though.)

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
 
Reply With Quote
 
 
 
 
Mike Pultz
Guest
Posts: n/a
 
      08-10-2010
On Aug 10, 1:47*am, Paavo Helde <(E-Mail Removed)> wrote:
> "(E-Mail Removed)" <(E-Mail Removed)> wrote in news:a9aaf2e4-d0b9-46b0-
> (E-Mail Removed):
>
> > 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.

>
> Sam has already answered your immediate question. Just a few more notes.
>
> In Linux, the threads are implemented as processes sharing the same
> memory space. When you call fork() in a multithreaded program, you will
> get a copy of the current thread and a copy of the whole memory space.
> This means that the memory space has lots of inaccessible stuff inside
> it, like dynamic allocations from other threads, stacks of the other
> threads etc. Carrying this garbage along is just not clean even if the
> program could be otherwise put to work. And yes, this inaccessible memory *
> can contain things like acquired user-space locks.
>
> So yes, if you want to clone your multithreaded process, then it would be
> wise to exec() yourself immediately after fork(), possibly with some
> special command-line arguments showing that you are starting an internal
> child, and passing over any needed information.


Thanks everyone- unfortunately, that's what I thought-

I would just use threads for everything, and no fork(), but the stupid
library I'm using uses lots of global static variables, and even has
some cases where it exit()'s from inside methods!!

I considered using execv() as well, but I'm using a socketpair() for
IPC, so it would make that pretty tough.

I guess I was just hoping for some magical "un-lock-everything()"
function I could call after I fork()'d

Jorgen- you are right- this is Linux specific, though I had a tough
time finding a good (competent) Linux C group- figured I'd ask here.

Cheers,

Mike
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Satellite P35-S609 locks up after a period of inactivity mazdra76@yahooo.com Computer Support 2 08-17-2005 04:28 AM
X64 locks up at SHUTDOWN sometimes - after running for a few days Gary J. Dikkema Windows 64bit 13 07-15-2005 05:30 PM
NT locks up after 4-5 minutes Jack B. Pollack Computer Support 6 01-05-2005 02:44 AM
Win2000 Machine locks up after 10-12 minutes... Carlos Computer Support 4 04-21-2004 10:55 AM
Help! Ext. USB2 HD locks up after 2 minutes. Anonymous Computer Support 3 11-17-2003 09:19 AM



Advertisments