2011-01-21 20 views
1

実際に必要なのは、* nix pthread識別子(pthread_t)のポータブルな比較とプリントです。 pthread_equal関数は2つのスレッドIDを比較するために存在しますが、いくつかの実装ではpthread_tが構造体へのポインタであるため、演算子< < => =>(もちろん移植可能です)と比較することはできません。そこで私は、共有したいと思っていたソリューションを見つけ出し、移植性について議論しました。ポータブルプリントと比較pthread_t

私たちはthred_idクラスラッパーを持っているとします。このラッパーは、それほど類似していない、等価比較可能な、もちろん印刷可能である必要があります。私は2つの部分的な特殊化を持つテンプレートクラスを作っています - ポインタ用と算術型用の1つ

template <typename T, bool A = is_arithmetic<T>::value> 
struct hash 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return hash<T*, A>::calculate(&thread_id); 
    } 
}; 

template <typename T> 
struct hash<T*, false> 
{ 
    static unsigned long calculate(T* thread_id) 
    { 
     std::size_t hash = 0; 
     if (char* data = reinterpret_cast<char*>(thread_id)) 
     { 
      for (int i = 0; i < sizeof(T); ++i) 
      { 
       hash = (hash << 6)^(hash >> 26)^data[i]; 
      } 
     } 
     return hash; 
    } 
}; 

template <typename T> 
struct hash<T, true> 
{ 
    static unsigned long calculate(T thread_id) 
    { 
     return static_cast<unsigned long>(thread_id); 
    } 
}; 

それはどうですか?我々は2つのスレッドIDを比較する必要がある場合、我々は単に

pthread_equal(tid1, tid2); 

を呼び出すが、オペレータ<のために我々はpthread_tが、我々はその後、ポインタとして実装されているのであれば、ここで

hash<pthread_t>::calculate(tid1) < hash<pthread_t>::calculate(tid2) 

を比較するためにハッシュを使用します指示されたオブジェクトのハッシュを計算します。

算術型の場合は、unsigned intにキャストしようとします。

構造体として実装されている場合は、構造体オブジェクト自体のハッシュを計算します。

ハッシュ値は、オペレータレスとスレッドID出力にのみ使用されます。

あなたはどう思いますか?このソリューションはどのように移植性があり、それ以上のものはありますか?

ありがとうございます。

+0

なぜ本来的に注文不可能な種類の注文を実施したいのですか?あなたは概念的に何を達成しようとしていますか? – FooF

答えて

1

pthread_tを比較するのではなく、スレッドの作成をカプセル化して、新しいスレッドをmap<some_id, pthread_t>に追加します。ここでidは生成され、ユニークです。次に、あなたは常にidによってスレッドを参照し、あなたが好きなように並べ替え、並べ替えることができます。

+0

実際には私はコンテナにスレッドを格納する必要はありません。私は、スレッドを書く必要があります。これは、関連コンテナに格納して比較して印刷することができます。もちろん、私はスレッドの作成とストアIDのいくつかのグローバルマップでハンドラを設定することができますが、それは私が探している解決策ではない、ほとんどの場合pthread_tは、システム内のスレッドを一意に表すartithmetical値であり、サロゲートIDを使用する – axe

0

pthread_tのデータ型は標準で固定されていませんので、pthread_compare()が提供されていると思います。

私のアプリケーションでは、Markが提案したように、pthread_tをいくつかの一意のIDにマッピングします。

here

+1

私はそれが修正されていないことを知っています。それは私が解決しようとしていることです。関数pthread_compareはありません。pthread_equalがあります。pthread_equalは、2つのスレッドIDの等価性のみをチェックします。私が話していることは、POSIXが提供していないより少ない演算子(operator <)と比較されるので、いくつか作ろうとしています。 – axe

1

がpthread_tを参照してくださいには、標準は、それが不透明タイプのものでなければならないと言う、それは構造体または共用体またはビットフィールド可能性があり、必ずしももスカラーデータ型ではありません。

スカラーpthread_tを含むpthread_tには、ハッシュ結果に影響する「ノイズ」を導入するパディングビットが含まれる場合があります。現時点では、ユーザーレベルでpthread_tを比較する普遍的な移植可能な方法はありません。

実際、pthread_tがポインタであるシステムでのpthread_equalは、2つの引数が実際に異なるスレッドを参照していても等価を返すことができます。スレッドは終了することができ、同じスレッド値、したがってpthread_t値を有する新しいスレッドを作成することができる。

マップが1:nである可能性があるため、逆引き参照を行う必要がない場合は、マップされた固有ID手法が機能します。継続的にスレッドを終了して作成すると、マップも非常に大きくなります。

関連する問題