3

次のコードがあります。ビルド アプリケーションは myprogram です。

myprogram を起動してから myprogram をすべて kill し、その直後に myprogram を再度起動すると、myprogram がクラッシュします。

クラッシュの原因は、最初の起動で作成された管理スレッドが 2 回目の起動の前に適切にクリアされていないことにあります。

そのため、myprogram が pthread を使用してスレッドを作成しようとする 2 回目の起動時に、古いスレッド管理がまだ削除されていないため、クラッシュが発生します。

最初の起動の終わり、またはCでの 2 回目の起動の開始時に管理スレッドを強制終了する方法はありますか?

#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 1 myprogram (1 for the main application)

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

    // ps aux | grep myprogram  ---> show 3 myprogram
    // (1st for the main application)
    // (2nd for the management thread. thread which manage all created thread)
    // (3rd for the created thread)

    sleep (20);  


    pthread_cancel(test_thread);

    // ps aux | grep myprogram  ---> show 2 myprogram and
    // (1st for the main application)
    // (2nd for the management thread. thread which manage all created thread)

    sleep(100);
    // in this period (before the finish of myprogram)
    // I execute killall to kill myprogram 
    // and then immediately I re-launch myprogram and then the program crash
    // because the management thread is not immediately killed

}

ところで:

Linuxの使用libuClibc-0.9.30.1.soとこの質問によると、スレッドをキャンセルした後、pthread_createで作成されたすべてのサブプロセスを強制終了する方法は? この libc は の Linux スレッド実装をpthread使用し、NPTL (「ネイティブ posix スレッド ライブラリ」) 実装で libc を使用しないため、管理スレッドはこの libc の場合にのみ作成されます。

4

1 に答える 1

5

RedhatのTheNativePOSIX Thread Library for Linux ペーパーに従って、スレッドマネージャーを強制終了しているため、この問題が発生していると思います。killall

マネージャースレッドが強制終了された場合、プロセスの残りの部分は手動でクリーンアップする必要がある状態になります。

また、Linuxスレッドモデルの比較

致命的なシグナルはすべてのスレッドを殺すことができます。この面でのLinuxThreadsの設計は一貫しています。プロセスが致命的なシグナルを受信すると、スレッドマネージャーは同じシグナルを持つ他のすべてのスレッド(プロセス)を強制終了します

つまり、スレッドマネージャーを強制終了しても、他のスレッドを強制終了する機会がないため、メインプロセスのみを強制終了する必要がありますkill -p pidkillall

メインプロセスが正常に存在するか、シグナルを受信した場合、スレッドマネージャーは、他のスレッドの強制終了と待機が完了すると、最終的には強制終了されると思いますがpthread_exit、他のすべてのプロセスを呼び出すと、に戻る前に強制終了されることにも言及しています。主要:

メインプロセスがpthread_exit()を呼び出した場合、プロセスは終了しません。メインスレッドはスリープ状態になり、他のすべてのスレッドが強制終了されたときにメインスレッドをウェイクアップするのはマネージャースレッドの仕事です。

于 2012-11-09T09:45:13.287 に答える