GNU/Linux >> Linux の 問題 >  >> Linux

pthread_exit と return

これにまだ興味があるかどうかはわかりませんが、現在、同様の状況をデバッグしています。 pthread_exit を使用するスレッド valgrind が到達可能なブロックを報告するようにします。その理由はここでかなりよく説明されているようです:

https://bugzilla.redhat.com/show_bug.cgi?id=483821

基本的には pthread_exit のようです dlopen を引き起こします プロセスの終了時に明示的にクリーンアップされることはありません。


次の最小限のテスト ケースは、あなたが説明した動作を示します:

#include <pthread.h>
#include <unistd.h>

void *app1(void *x)
{
    sleep(1);
    pthread_exit(0);
}

int main()
{
    pthread_t t1;

    pthread_create(&t1, NULL, app1, NULL);
    pthread_join(t1, NULL);

    return 0;
}

valgrind --leak-check=full --show-reachable=yes pthread_exit() によって呼び出された関数から割り当てられた 5 つのブロックを示します これは解放されていませんが、プロセスの終了時にまだ到達可能です。 pthread_exit(0); の場合 return 0; に置き換えられます 、5 つのブロックが割り当てられていません。

ただし、多数のスレッドの作成と結合をテストすると、終了時に使用されている解放されていないメモリの量が そう ないことがわかります。 増加。これと、まだ到達可能であるという事実は、glibc 実装の奇妙さを見ているだけであることを示しています。いくつかの glibc 関数は malloc() でメモリを割り当てます 最初に呼び出されたとき、残りのプロセスの存続期間に割り当てられたままになります。 glibc は、プロセスが破棄されていることを認識しているため、プロセスの終了時にこのメモリを解放することはしません。CPU サイクルの浪費になるだけです。


もしかして、あなたは実際に C++ を使っていますか?明確にするために、ソースファイルは .c で終わります 拡張機能であり、gcc でコンパイルしています 、 g++ ではありません ?

関数が返されたときに自動的にクリーンアップされると予想されるリソースを関数が割り当てている可能性がかなり高いようです。 std::vector などのローカル C++ オブジェクト または std::string これを行うと、 pthread_exit を呼び出すと、デストラクタが実行されない可能性があります 、しかし、あなたが戻るだけで片付けられます。

pthread_exit などの低レベル API は避けるのが私の好みです 、可能な場合は常にスレッド関数から戻ります。 pthread_exit 以外は同等です は、使用している言語をバイパスする事実上のフロー制御構造ですが、 return


Linux
  1. なぜCdはプログラムではないのですか?

  2. プロセスの子孫?

  3. 中断できないプロセスとは何ですか?

  1. CHILD PROCESSから戻り値を取得するには?

  2. malloc(0) は何を返しますか?

  3. pthread 開始関数での return() と pthread_exit() の比較

  1. Linux の CreateProcess?

  2. セグメンテーション違反を起こしたプロセスが返すエラー コードは何ですか?

  3. ゾンビプロセスの作成