Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Thread problems on linux

7 views
Skip to first unread message

vineet

unread,
Jul 16, 2003, 11:51:20 PM7/16/03
to
Kasper Dupont <kas...@daimi.au.dk> wrote in message news:<3F14FFAE...@daimi.au.dk>...
> vineet wrote:
> >
> > Hi All,
> >
> > I am observing that sometimes my multithreaded application crashes
> > leaving behind individual threads as independent defunct processes.
> > E.g. If a Process X has 3 threads a,b,c. After a while (observed that
> > usually the thread manager thread crashes), then after the crash I see
> > a,b,c as individual processes, each behving independent of other.
>
> A defunct process staying for a long time indicates a problem in the
> parent process. Which process is listed as parent of those defunct
> processes?

Yes and No. I think a child will remain zombie (defunt) if the parent
has not ignored the SIGCHILD or called wait() etc.... However, the
main issue is not - why the defunct process is there but what about
the other threads that become independent processes. How to ensure
that a proper cleanup happens. To explain in detail -
Process X has 3 threads A,B,C. In the process table there are 5
processes - 1 for the process X, 1 for thread manager, and 1 each for
threads A,B,C. Process X is parent of thread manager and thread
manager is parent of processes A,B,C. Now, if thread manager process
is killed, processes A,B,C inherit init (process id 1) as their parent
(normal behaviour for any process whose parent dies). In effect,
process X and A,B,C are totally seperate now, no relation exists
between these. Thread manager thread shows up as a defunt process
(probably because process X did not handle the SIGCHILD etc...)

I was going through some linux documentation and suggests that thread
groups are implemented so that thread in a sinlge process have the
same thread group and then 1 thread can wait on signals for all
threads in the same group. In the example above, the thread group
visible in the /proc file system was their own PID. Not sure if I
have been able to explain my problem and thought correctly, but in
summary - I am looking at a proper cleanup in case the thread manager
thread dies for any reason (which I am observing on my RH 8.0 setup)

Thanks
Vineet

David Schwartz

unread,
Jul 17, 2003, 2:51:00 PM7/17/03
to

"vineet" <vinee...@yahoo.com> wrote in message
news:a13a3158.03071...@posting.google.com...

> Process X has 3 threads A,B,C. In the process table there are 5
> processes - 1 for the process X, 1 for thread manager, and 1 each for
> threads A,B,C.

If a process has 3 threads, there will only be four processes in the
process table. Perhaps you mean a process *creates* 3 threads (in addition
to the one it started with that called main).

> Process X is parent of thread manager and thread
> manager is parent of processes A,B,C. Now, if thread manager process
> is killed, processes A,B,C inherit init (process id 1) as their parent
> (normal behaviour for any process whose parent dies).

What do you mean "if the thread manager is killed"? Killed how? By what?

> In effect,
> process X and A,B,C are totally seperate now, no relation exists
> between these. Thread manager thread shows up as a defunt process
> (probably because process X did not handle the SIGCHILD etc...)

Do you know of any threading library that guarantees sane handling if
some external force suddenly and completely kills one of its threads?

> I was going through some linux documentation and suggests that thread
> groups are implemented so that thread in a sinlge process have the
> same thread group and then 1 thread can wait on signals for all
> threads in the same group. In the example above, the thread group
> visible in the /proc file system was their own PID. Not sure if I
> have been able to explain my problem and thought correctly, but in
> summary - I am looking at a proper cleanup in case the thread manager
> thread dies for any reason (which I am observing on my RH 8.0 setup)

The thread manager thread must not die for any reason. Your problem is
that the thread is dying, not what happens after that.

DS


vineet

unread,
Jul 17, 2003, 11:29:26 PM7/17/03
to
"David Schwartz" <dav...@webmaster.com> wrote in message news:<bf6r6l$52u$1...@nntp.webmaster.com>...

But that is what is happening. Thread Manger is *dying*. I am sure
its because of some screw up in application code but its happening.
Anyways I have found a solution that seems to work. If the main
thread (the main() { } of the program), after spawning all the other
threads blocks on a waitpid() with __WCLONE option, it gets a signal
and returns from waitpid() when the thread manager dies. If it calls
a kill(0,SIGKILL), proper clean up happens, there are no processes
left behind with init as parent. Sample code attachcd. I use pstack
to see all the thread (with their pids) for the process, then send a
kill signal to the thread manager from outside to kill it.


#define __REENTRANT
#include <iostream.h>
#include <pthread.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>

#define NUM_THREADS 2
#define SLEEP_TIME 10

void *firstThr(void *); /* thread routine */
void *secondaryThr(void *); /* thread routine */

int i;

pthread_t tid[NUM_THREADS]; /* array of thread IDs */

int main(int argc, char *argv[]) {

pid_t pppid;

// create threads

for ( i = 0; i < NUM_THREADS; i++) {
pthread_create(&tid[i], NULL, firstThr, (void *)SLEEP_TIME);
cout << "created primary thread with thread id " << tid[i] << endl;
pthread_detach(tid[i]);
}

// wait for a thread to exit

// comment the following lines till next comment to simulate the
problem

pppid = waitpid(0,0,__WCLONE);

cout << "PID of thread that exited - 1 " << pppid << endl;

kill(0,SIGKILL);

// uncomment the following to see the problem
//for(;;)
// sleep(10);

}

// this thread creates another thread, then sleeps in a loop and never
returns

void * firstThr(void *arg) {
int sleep_time = (int)arg;

pthread_create(&tid[i], NULL, secondaryThr, (void *)SLEEP_TIME);
cout << "created secondary thread" << endl;
i++;
pthread_detach(tid[i]);
for(;;)
sleep(sleep_time);
}

// this thread sleeps for a while and then exits
void * secondaryThr(void *arg) {
int sleep_time = (int)arg;
for(int y=0;y<1;y++)
sleep(sleep_time);

cout << "secondary thread exiting " << endl;
pthread_exit(0);
}

Patrick TJ McPhee

unread,
Jul 18, 2003, 11:11:40 AM7/18/03
to
In article <a13a3158.03071...@posting.google.com>,
vineet <vinee...@yahoo.com> wrote:
% "David Schwartz" <dav...@webmaster.com> wrote in message
% news:<bf6r6l$52u$1...@nntp.webmaster.com>...

% > Do you know of any threading library that guarantees sane handling if
% > some external force suddenly and completely kills one of its threads?

Most threading libraries don't allow external forces to suddenly and
completely kill a single thread. If an internal force suddenly kills
a thread, most threading libraries take down the entire process. If
you mean on Linux specifically, NPTL is supposed to have this behaviour.

% Anyways I have found a solution that seems to work.

[...]

You should know that whatever you're doing is specific to a soon-to-be
obsolescent thread implementation. You should be prepared to scuttle
all the hacks so that you can build on other platforms, or on the
same platform once the 2.6 kernel is available.

--

Patrick TJ McPhee
East York Canada
pt...@interlog.com

0 new messages