0

I have the following code and I make ps aux | grep myprogram in each step of the main() code of myprogram (name of the application I build).

At the beggining of the execution of myprogram, the ps aux | grep myprogram show only 1 time the myprogram in the list

after cancelling a thread that I created in the begging of the main(), the ps aux | grep myprogram show the myprogram twice and I expected to get only 1.

Could some one explain this behaviour? and how to return to the initial situation (only 1 myprogram)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

pthread_t test_thread;

void *thread_test_run (void *v)
{
    int i=1;
    while(1)
    {
       printf("into thread %d\r\n",i);
       i++; 
       sleep(1);
    }
    return NULL
}

int main()
{
    // ps aux | grep myprogram  ---> show only 1 myprogram

    pthread_create(&test_thread, NULL, &thread_test_run, NULL);

    // ps aux | grep myprogram  ---> show  3 myprogram

    sleep (20);  


    pthread_cancel(test_thread);

    // ps aux | grep myprogram  ---> show 2 myprogram and I expected only 1 !!??

   // other function are called here...

    return 0;
}

EDIT

the libc used by the linux is libc-0.9.30.1.so

# ls -l /lib/| grep libc
-rwxr-xr-x    1 root     root        16390 Jul 11 14:04 ld-uClibc-0.9.30.1.so
lrwxrwxrwx    1 root     root           21 Jul 30 10:16 ld-uClibc.so.0 -> ld-uClibc-0.9.30.1.so
lrwxrwxrwx    1 root     root           21 Jul 30 10:16 libc.so.0 -> libuClibc-0.9.30.1.so
-rw-r--r--    1 root     root         8218 Jul 11 14:04 libcrypt-0.9.30.1.so
lrwxrwxrwx    1 root     root           20 Jul 30 10:16 libcrypt.so.0 -> libcrypt-0.9.30.1.so
-rw-r--r--    1 root     root       291983 Jul 11 14:04 libuClibc-0.9.30.1.so
4

3 回答 3

3

I'll assume you have some outdated glibc (version 2.2 or 2.3), which used the "linuxthreads" implementation of pthread.

In this older library one additional thread is created by the library for thread management; it can be created after first call to pthread_create; but it will sleep most time.

In newer linuxes there is glibc with NPTL ("Native posix thread library") implementation. When it is used, you will not see threads in ps axu; use ps axum (with m) to see native threads. And NPTL not uses a management thread.

PS Check http://pauillac.inria.fr/~xleroy/linuxthreads/faq.html D.5 answer:

D.5: When I'm running a program that creates N threads, top or ps display N+2 processes that are running my program. What do all these processes correspond to?

Due to the general "one process per thread" model, there's one process for the initial thread and N processes for the threads it created using pthread_create. That leaves one process unaccounted for. That extra process corresponds to the "thread manager" thread, a thread created internally by LinuxThreads to handle thread creation and thread termination. This extra thread is asleep most of the time.

PPS: Thanks, Mohamed KALLEL; thanks, mux: libc-0.9.30.1 is uClibc and seems that it uses same outdated linuxthreads implementation (which is known to be not fully posix-compatible). Here is changelog: http://web.archive.org/web/20070609171609/http://www.uclibc.org/downloads/Changelog

0.9.10 21 March 2002

Major new features: o pthreads support (derived from glibc 2.1.3's linuxthreads library) by Stefan Soucek and Erik Andersen

于 2012-11-08T14:02:38.783 回答
0

Could be an older pthreads implementation as suggested by the other answers, however, if you are using a glibc 2.4 or higher which uses NPTL, then note that the ps command you used won't even show threads, instead use:

ps -AL

The output before and after pthread_cancel() is:

$ ps -AL | grep tst
  983   983 pts/2    00:00:00 tst
  983   984 pts/2    00:00:00 tst
$ ps -AL | grep tst
  983   983 pts/2    00:00:00 tst

There's more information about it here specifically about uclibc since it doesn't have NPTL, then ps aux should show all the threads.

Since the introduction of the Native POSIX Threads Library (NPTL) threads have become rather elusive. They don't show up in the default process listing using the ps command if you do have the luxury of the full ps command (from the procps package) on your target system then all you need to do is add the “-L” option.

于 2012-11-08T14:01:42.637 回答
0

You have an (very) old linux system, where your threads are shown as processes by tools such as ps, which will not happen on newer linux systems

However, a thread is normally not entierly disposed of when it returns or you kill/cancel it.

For that to happen you have to call pthread_detach(pthread_self()) in your thread or create the thread in detached state: A detached thread will dispose it's thread resources when that thread ends, and a detached thread cannot be joined by pthread_join() later.

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 1);
pthread_create(&test_thread, &attr, &thread_test_run, NULL);

Or you have to call pthread_join() on it, e.g.

pthread_create(&test_thread, NULL, &thread_test_run, NULL);

sleep (20);  
pthread_cancel(test_thread);
pthread_join(test_thread);

pthread_join() will ensure the thread resources are released.

The concept is roughly analogous to zombie processes, where a process is not entierly disposed of until a parent calls wait() or similar on that process.

于 2012-11-08T14:10:19.943 回答