質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

POSIX

POSIXは、UNIX系OSでの共通機能などを維持するための標準を策定した規格。POSIX仕様によって開発したプログラムは、POSIXに準じたOSであればどれも同じように動作させることが可能です。

Q&A

1回答

2280閲覧

posixのtimer_create関数内で確保されるメモリはどのように解放するのか

Ykkykk

総合スコア140

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

POSIX

POSIXは、UNIX系OSでの共通機能などを維持するための標準を策定した規格。POSIX仕様によって開発したプログラムは、POSIXに準じたOSであればどれも同じように動作させることが可能です。

0グッド

0クリップ

投稿2020/10/19 03:01

編集2020/10/19 05:13

表題の件につきましてお尋ねしたいです。

POSIXのtimer_create関数を使用すると、valgrindでメモリリークを検知してしまいます。検知を抑制すれば済む問題ではあるのですが、timer_create関数のソースコードを見ると、timer_create関数から作成されているヘルパー関数のスレッドが終了しないということが原因になっているように思います。
メモリリークしていないのかもしれないのですが、timer_create関数内で生成されたスレッドは終わらないのがデフォルトの挙動という理解でよいのでしょうか?

以下のコードをvalgirnd経由で実行すると、下部に記載するメモリのサマリが表示されます。

C

1#include <inttypes.h> 2#include <pthread.h> 3#include <signal.h> 4#include <stdint.h> 5#include <stdio.h> 6#include <stdlib.h> 7#include <string.h> 8#include <unistd.h> 9 10const struct itimerspec its = { .it_value = { 1 } }; 11const struct timespec ts = { 3 }; 12 13void notifyFunc(union sigval sv) 14{ 15 printf("notifyfunc: timer has expired.\n"); 16} 17 18int main(void) 19{ 20 struct sigevent se; 21 struct sigaction sa; 22 timer_t timerid_thread; 23 timer_t timerid_signal; 24 25 memset(&se, 0, sizeof(se)); 26 se.sigev_value.sival_int = 1; 27 se.sigev_notify = SIGEV_THREAD; 28 se.sigev_notify_function = notifyFunc; 29 se.sigev_notify_attributes = NULL; 30 timer_create(CLOCK_REALTIME, &se, &timerid_thread); 31 timer_settime(timerid_thread, 0, &its, NULL); 32 33 nanosleep(&ts, NULL); 34 35 int res; 36 res = timer_delete(timerid_thread); 37 printf("TIMER_DELETE RES: %d\n", res); 38 39 return 0; 40}

valgrindのサマリ

==28846== HEAP SUMMARY: ==28846== in use at exit: 272 bytes in 1 blocks ==28846== total heap usage: 10 allocs, 9 frees, 3,366 bytes allocated ==28846== ==28846== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1 ==28846== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==28846== by 0x40134F6: allocate_dtv (dl-tls.c:286) ==28846== by 0x40134F6: _dl_allocate_tls (dl-tls.c:530) ==28846== by 0x504C227: allocate_stack (allocatestack.c:627) ==28846== by 0x504C227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644) ==28846== by 0x4E4151A: __start_helper_thread (timer_routines.c:176) ==28846== by 0x5053826: __pthread_once_slow (pthread_once.c:116) ==28846== by 0x4E403BA: timer_create@@GLIBC_2.3.3 (timer_create.c:101) ==28846== by 0x1089C6: main (in /home/xxx/sample/sample_timer_2) ==28846== ==28846== LEAK SUMMARY: ==28846== definitely lost: 0 bytes in 0 blocks ==28846== indirectly lost: 0 bytes in 0 blocks ==28846== possibly lost: 272 bytes in 1 blocks ==28846== still reachable: 0 bytes in 0 blocks ==28846== suppressed: 0 bytes in 0 blocks

上記に表示されているスレッドはメインの処理が終わった後も残り続けているのだと思うのですが、問題ないのでしょうか?
ご教示いただけますと幸いです。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

同じ状況を検証できる環境にないので推測での回答ですが、time_create()で登録するハンドラーは、pthread_exit()で終了させるものではないように思います。Pthreads(POSIXスレッド)とは少しカテゴリが違う関数群のはずです。

pthread_exit()の呼び出しを止めてみたら状況が変わりませんでしょうか。

C

1void notifyFunc(union sigval sv) 2{ 3 printf("notifyfunc: timer has expired.\n"); 4 5/* 6 pthread_exit(NULL); 7*/ 8}

投稿2020/10/19 04:53

編集2020/10/19 04:55
dodox86

総合スコア9183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/10/19 05:01

表題の「posixのtimer_create関数内で確保されるメモリはどのように解放するのか」を解決する回答ではありませんが、使っているコードに問題があるのではないか、と言う視点から回答させていただきました。
Ykkykk

2020/10/19 05:07

ご回答いただきありがとうございます。 そちらのpthread_exitはもともとつけていなかったのですが、ハンドラー関数のスレッドが終わってないのかと思いつけてみていました。 このpthread_exitがなくてもあってもvalgrindで表示されるメモリリークは同じなのです。。。 timer_create関数の中でヘルパー関数が別のスレッドとして起動されており、そちらの関数を止めることができていない形です。 ご回答いただきありがとうございます!
Ykkykk

2020/10/19 05:14

上記のご指摘を本文に反映いたしました。
dodox86

2020/10/19 05:15

> そちらのpthread_exitはもともとつけていなかったのですが、ハンドラー関数のスレッドが終わってないのかと思いつけてみていました。 なるほど、そうだったのですね。もしLinux下での実行なのであれば、Ptheradライブラリで扱われるLinuxのスレッドはcloneシステムコールで生成される同じメモリを共有するプロセスなので、main()が終わってもcloneされたスレッド側の何かが残っているのかもしれませんね。引き続き有識者の方からの回答をお待ちいただければと思います。お役に立てずすみません。
Ykkykk

2020/10/19 05:18

いえ、むしろお忙しいところご回答いただきありがとうございます! Ubuntuで実行しているのでおっしゃっているようにメイン関数終了後にも恐らくですがヘルパー関数のスレッド自体が残ってしまっているのだと思います。。。 何はともあれ、ご回答いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問