0

次のコードがあり、 myprogram (ビルドするアプリケーションの名前ps aux | grep myprogram) の main() コードの各ステップで作成します。

myprogramの実行開始時に、リスト内のmyprogramps aux | grep myprogram1 回だけ表示します。

の開始時に作成したスレッドをキャンセルした後、 myprogramを 2 回表示しましたがmain()、取得できるのは 1 つだけでした。ps aux | grep myprogram

誰かがこの振る舞いを説明できますか? および初期状態に戻す方法 (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;
}

編集

Linuxで使用されるlibcは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

pthread の「linuxthreads」実装を使用した、古い glibc (バージョン 2.2 または 2.3) があると仮定します。

この古いライブラリでは、スレッド管理用にライブラリによって 1 つの追加スレッドが作成されます。pthread_create を最初に呼び出した後に作成できます。しかし、それはほとんどの時間眠ります。

新しい Linux には、NPTL (「ネイティブ posix スレッド ライブラリ」) 実装を備えた glibc があります。使用すると、スレッドが表示されなくなりps axuます。ps axum(とともに) を使用しmて、ネイティブ スレッドを表示します。また、NPTL は管理スレッドを使用しません。

PS チェックhttp://pauillac.inria.fr/~xleroy/linuxthreads/faq.html D.5 回答:

D.5: N 個のスレッドを作成するプログラムを実行しているときに、top または ps は、プログラムを実行している N+2 プロセスを表示します。これらすべてのプロセスは何に対応していますか?

一般的な「スレッドごとに 1 つのプロセス」モデルにより、初期スレッド用に 1 つのプロセスがあり、pthread_create を使用して作成されたスレッド用に N 個のプロセスがあります。これにより、1 つのプロセスが不明のままになります。その余分なプロセスは、「スレッド マネージャー」スレッドに対応します。これは、スレッドの作成とスレッドの終了を処理するために LinuxThreads によって内部的に作成されるスレッドです。この余分なスレッドは、ほとんどの場合スリープ状態です。

PPS: ありがとう、モハメド・カレル。ありがとう、mux: libc-0.9.30.1 は uClibc であり、同じ古い linuxthreads 実装を使用しているようです (完全には posix 互換ではないことが知られています)。ここに変更ログがあります: http://web.archive.org/web/20070609171609/http://www.ulibc.org/downloads/Changelog

0.9.10 2002 年 3 月 21 日

主な新機能: o pthreads のサポート (glibc 2.1.3 の linuxthreads ライブラリから派生) Stefan Soucek と Erik Andersen による

于 2012-11-08T14:02:38.783 に答える
0

(非常に)古いLinuxシステムがあり、スレッドはなどのツールによってプロセスとして表示されますがps、新しいLinuxシステムでは発生しません。

ただし、通常、スレッドが戻ったとき、またはスレッドを強制終了/キャンセルしたときに、スレッドは完全に破棄されません。

そのためには、スレッドを呼び出すpthread_detach(pthread_self())か、切り離された状態でスレッドを作成する必要があります。切り離されたスレッドは、そのスレッドが終了したときにスレッドリソースを破棄し、切り離されたスレッドは後でpthread_join()で結合できません。

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

または、pthread_join()を呼び出す必要があります。

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

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

pthread_join()は、スレッドリソースが解放されることを保証します。

この概念は、親がそのプロセスでwait()などを呼び出すまで、プロセスが完全に破棄されないゾンビプロセスにほぼ類似しています。

于 2012-11-08T14:10:19.943 に答える
0

他の回答で示唆されているように、古いpthreads 実装である可能性がありますが、NPTL2.4を使用する glibc以降を使用している場合、使用した ps コマンドではスレッドが表示されず、代わりに次を使用することに注意してください。

ps -AL

前後の出力pthread_cancel()は次のとおりです。

$ 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

NPTL がないため、詳細についてはこちらをご覧ください。すべてのスレッドを表示する必要があります。uclibcps aux

ネイティブ POSIX スレッド ライブラリ (NPTL)の導入以来、 スレッドはかなりとらえどころのないものになっています。ターゲット システムで完全な ps コマンド (procps パッケージから) を使用できる場合は、ps コマンドを使用したデフォルトのプロセス リストには表示されません。その場合は、「-L」オプションを追加するだけです。 .

于 2012-11-08T14:01:42.637 に答える