web-dev-qa-db-ja.com

pthread_create使用時のvalgrindメモリリークエラー

私はpthreadライブラリを使用してプログラムを書いています。コマンドvalgrind --leak-check=fullを使用してプログラムを実行すると、次のエラーの説明が表示されます。

==11784==  
==11784== **HEAP SUMMARY:**  
==11784==     in use at exit: 4,952 bytes in 18 blocks  
==11784==   total heap usage: 1,059 allocs, 1,041 frees, 51,864 bytes allocated  
==11784==  
==11784== **288 bytes** in 1 blocks are possibly lost in loss record 2 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)  
==11784==    by 0x401BC0: initdevice(char*) (in /a/fr-01/vol/home/stud/lim/workspace  /Ex3/l)  
==11784==    by 0x406D05: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **4,608 bytes** in 16 blocks are possibly lost in loss record 3 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)    
==11784==    by 0x40268F: write2device(char*, int) (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==    by 0x406D7B: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **LEAK SUMMARY:**  
==11784==    definitely lost: 0 bytes in 0 blocks  
==11784==    indirectly lost: 0 bytes in 0 blocks  
==11784==      possibly lost: 4,896 bytes in 17 blocks  
==11784==    still reachable: 56 bytes in 1 blocks  
==11784==         suppressed: 0 bytes in 0 blocks  
==11784== Reachable blocks (those to which a pointer was found) are not shown.  
==11784== To see them, rerun with: --leak-check=full --show-reachable=yes  
==11784==  
==11784== For counts of detected and suppressed errors, rerun with: -v  
==11784== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)  

特定の関数を使用してpthread_createを呼び出すたびに、関数の最後で関数pthread_exitを呼び出します。それで、これが問題ではないことを確認した後、何が問題になる可能性がありますか?

21
lim

スレッドがdetach state属性をPTHREAD_CREATE_DETACHEDに設定して作成された場合、またはpthread_detachがそのpthread_tに対して呼び出された場合を除き、スレッドのリソースは終了時にすぐには解放されません。

切り離されていないスレッドは、その識別子がpthread_joinまたはpthread_detachに渡されるまで終了状態のままになります。

要約すると、次の3つのオプションがあります。

  1. 切り離された属性セット(PTHREAD_CREATE_DETACHED属性)を使用してスレッドを作成します
  2. 作成後にスレッドを切り離す(pthread_detachを呼び出す)、または
  3. 終了したスレッドと結合してリサイクルします(pthread_joinを呼び出します)。

H番目。

36
Alok Save

参加可能なスレッドを使用していない場合、既存のスレッドはすべてのリソースを解放するためにpthread_detach(pthread_self())を呼び出す必要があります。

5
micha

スレッドを結合する必要がない場合(またはスレッド自体で期限切れになる場合)にメモリリークを回避するために、スレッドを 切り離された状態で にすることができます。

スレッドを結合可能または分離として明示的に作成するには、pthread_create()ルーチンのattr引数を使用します。典型的な4ステップのプロセスは次のとおりです。

  • _pthread_attr_t_データ型のpthread属性変数を宣言します
  • pthread_attr_init()で属性変数を初期化します
  • pthread_attr_setdetachstate()で属性デタッチステータスを設定します
  • 完了すると、pthread_attr_destroy()で属性によって使用されるライブラリリソースが解放されます。
4
sehe

デフォルトのpthread_createの動作は「結合可能」であり、切り離されていないことに注意してください。したがって、一部のOSリソースは、pthreadが終了した後もプロセスに残り、ゾンビpthreadが発生し、仮想/常駐メモリの使用量が増加します。

@seheが言及した4つの解決策は、この問題を修正します。

ただし、スレッドが長年のものである場合、これは実際には必要ない場合があります。たとえば、pthreadがプロセスの全期間を通じて存続する場合です。

0
Aaron He

他のユーザーからの正解に加えて、これを読むことをお勧めします。

マルチスレッドCアプリケーションでのメモリリークの追跡

0
Kyrol