2011-01-24 13 views
4

スレッドローカルクリーンアップのために、現在のスレッドがboost :: threadによって作成されたかどうかを確認するアサーションを作成する必要があります。これが事実かどうかどうすれば確認できますか?つまり、現在のスレッドがboost :: threadによって処理されるかどうかを確認するにはどうすればいいですか?スレッドがブーストスレッドかどうかをチェック

スレッドが終了したときにスレッドローカルストレージのクリーンアップを行うには、これが必要です。ブーストのthread_local_ptrは、スレッド自体がブーストスレッドである場合にのみ動作するように見えます。

私はクリーンアップ時にチェックを行っていませんが、スレッドの寿命中はいつかチェックしています。いくつかの関数はAPI /コールバックの1つを(間接的に)呼び出してスレッドローカルストレージを割り当てます。ブーストスレッドだけがこれを行うことができます。そのため、スレッドがブーストスレッドでない場合は、その瞬間に検出する必要があります。


一般的なクリーンアップハンドラを持たない問題については、Destruction of static class members in Thread local storageを参照してください。私はそれに答え、pthread_clenaup_pushが実際には動作しないことを認識しました。スレッドからクリーンな終了フォームで呼び出されません。


私はブーストスレッドを検出する答えはありませんが、選択した答えは私の問題の根本を解決します。ブーストthread_specific_ptrは任意のpthreadでクリーンアップを呼び出します。それは孤立したテストが動作することを示すので、それが私のために働かない原因となっているに違いありません。

+6

私はあなたが本当に静的*アサーションを望んでいるとは思わない。静的アサーションはコンパイル時にチェックされますが、実行時に何かが作成されたかどうかをチェックするには早すぎます。普通の主張がほしいと思う。 –

+0

私は静的アサーションを修正しました。 –

答えて

3

あなたの質問の前提は誤っています:) boost :: thread_specific_ptrは、スレッドがブーストスレッドでなくても機能します。それについて考えてみましょう - ブーストによって作成することは不可能なので、メインスレッドのための特定のストレージをどのようにスレッド化するのでしょうか?私はboost :: thread_specific_ptrをメインスレッドからうまく使いましたが、boost :: thread_specific_ptrの実装を調べていませんが、実装する最も明白な方法は非ブーストスレッドでも機能します。ほとんどのオペレーティングシステムでは、現在のスレッドの一意のID番号を取得できます。このID番号は、マップ/配列/ハッシュテーブルのインデックスとして使用できます。

他のバグが発生している可能性があります。予期しない動作を示す小さなコンパイル可能なコードサンプルを使用して別の質問を開く必要があります。

+0

私はそれがどのように動作するかを把握しようとしています。このpthread関数はどのように機能しますか?私はそれが実際にあるかどうかを確認するためにテストを実行しています。 –

+0

これは、pthread_key_createの呼び出しがデストラクタを受け入れることを示しています。だから、これは私のためには十分ですが、スレッドがpthreadsで作成されていないとどうなりますか? ;) –

+0

私は実際にpthread_self()を考えていました。これはあなたに現在のスレッドの一意の整数を与えます。 pthread_key *関数はより効率的ですが、 LinuxのELF ABIでは、スレッドローカルストレージを特別にサポートしているので、特別なレジスタの形で直接CPUをサポートしなければならないと思っています。pthread_key_ *はそれらを利用するかもしれません。 pthreadsで作成されていない限り、あなたは子供ですが、複数のスレッド実装がOS上で利用可能な場合、それらはすべて同じコアに縮小される可能性があります。 –

0

静的アサーションではこれを行うことはできません。つまり、コンパイル時にそれを検出でき、それは不可能です。

あなたは他の方法とboost::threadを混在させない場合は、問題がちょうど消える:

あなたがが実行時にチェックを意味すると仮定。スレッドを作成しているライブラリは、すでに自分のスレッドを自動的に処理している必要があります(または、シャットダウン関数ごとに呼び出す必要があるAPIドキュメント)。

そうでなければ、boost::threadを使用せずに作成したすべてのpthread_tのコンテナを保持し、シャットダウン時にそのスレッドがコンテナに入っているかどうかを確認できます。コンテナ内にない場合は、boost::threadを使用して作成されました。

EDIT:boost::threadで作成されたかどうかを検出する代わりに、boost::threadで作成されたスレッドでのみAPIコールバックが発生するようにアプリケーションを設定することを検討しましたか?このようにすれば、問題を未然に防ぐことができ、存在していても実装するのは辛いという点検の必要性がなくなります。

+0

申し訳ありません、はい、ランタイムアサーションです。問題は、サードパーティライブラリからのコードへのコールバックにあります。 –

0

ブーストスレッドが終了するたびに、Thread Specific Dataがすべて駆除されます。 TSDはポインタで、破壊/リセット時にdelete p*を呼び出します。

オプションで、delete p*の代わりに、各アイテムに対してクリーンアップハンドラが呼び出されることがあります。そのハンドラはTLSコンストラクタで指定されており、クリーンアップ機能を使用して一度のクリーニングを行うことができます。

#include <iostream> 
#include <boost/thread/thread.hpp> 
#include <boost/thread/tss.hpp> 

void cleanup(int* _ignored) { 
    std::cout << "TLS cleanup" << std::endl; 
} 

void thread_func() { 
    boost::thread_specific_ptr<int> x(cleanup); 
    x.reset((int*)1); // Force cleanup to be called on this thread 

    std::cout << "Thread begin" << std::endl; 
} 

int main(int argc, char** argv) { 
    boost::thread::thread t(thread_func); 

    t.join(); 

    return 0; 
} 
+0

質問は、スレッドがboost :: threadでない場合、これは実際にデータのクリーンアップを保証しますか? –

関連する問題