プロフィール

kosaki

Author:kosaki
連絡先はコチラ

ブログ検索
最近の記事
最近のコメント
最近のトラックバック
リンク
カテゴリー
月別アーカイブ
RSSフィード
FC2ブログランキング

スポンサーサイト このエントリーをはてなブックマークに追加

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


スポンサー広告 | 【--------(--) --:--:--】 | Trackback(-) | Comments(-)

glibcのpthread_cancel()はC++と一緒に使うと予想外の動きをする事がある このエントリーをはてなブックマークに追加

http://udrepper.livejournal.com/21541.html

Ulrichがpthread_cancel()とC++は混ぜるなキケンになってるけど、オレは正しいんだ正しいんだ正しいんだ。
という趣旨のブログを書いております。

以下いつものように(主に笑いをとるための)超訳。正確な情報が欲しい人は元URLを読んでくださいませ。



#include <cstdlib>
#include <iostream>
#include <pthread.h>

static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;

static void *tf (void *)
{
try {
::pthread_mutex_lock(&m);
::pthread_cond_wait (&c, &m);
} catch (...) {
// do something
}
}

int main ()
{
pthread_t th;
::pthread_create (&th, NULL, tf, NULL);
// do some work; simulate using sleep
std::cout << "Wait a bit" << std::endl;
sleep (1);
// cancel the child thread
::pthread_cancel (th);
// wait for it
::pthread_join (th, NULL);
}


pthread_cacnel()は内部実装にC++例外を使ってる。だから、このようなコードは
tf() で pthread_cond_wait() から上がってきた秘密のglibc専用例外をキャッチしてしまい、
かつ、例外のrethowをしていないので、C++界の重罪、rethrow忘れの罪によりプロセスは
abortしてしまう


$ ./test
Wait a bit
FATAL: exception not rethrown
Aborted (core dumped)



正しい直し方は gcc specialな <cxxabi.h> をインクルードして、同じくスペシャルな
abi::__forced_unwind& をrethrowすることだよ。以下のように


@@ -1,6 +1,7 @@
#include
#include
#include
+#include

static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
@@ -11,6 +12,8 @@
try {
::pthread_mutex_lock(&m);
::pthread_cond_wait (&c, &m);
+ } catch (abi::__forced_unwind&) {
+ throw;
} catch (...) {
// do something
}


cxxabi.h はたしかgcc 4.3以降で提供されてるはず。
まあ、こんなの以下のマクロで一発解決できるんだから問題のうちにも入らないよ

#define CATCHALL catch (abi::__forced_unwind&) { throw; } catch (...)

だから、オレは直さなくていいよね。

オレは正しいんだ正しいんだ正しいんだ。

関連記事


linux | 【2010-08-05(Thu) 17:15:14】 | Trackback:(0) | Comments:(0)
  1. 無料アクセス解析
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。