2016-08-09 16 views
3

は、私たちが同時またはない使用することができますいくつかの新しいクラスを作成したとします。明らかに、私たちは同時に呼び出される機会に全てをロックしたくありません。これに対処する1つの方法は、mixins指定ロッキングによってパラメータ化によるものである。汎用コンポーネントフレンドリー

template<class Locking> 
struct foo : private Locking { 
    void bar() { 
     Locking::read_lock(); 
     // Do something. 
     Locking::read_unlock(); 
    } 
}; 

実際マルチスレッディング場合のロッククラスと、それ以外の場合(願わくは、のための-OPSもしないクラスとLockingをインスタンス化しますコンパイラは呼び出しを最適化します)。

は今、私が代わりにロックのソフトウェアトランザクショナルメモリでこれを行うにはしたいと思いますとします。 N3919(またはgcc precursor)を見ると、そのアイデアは異なります。このよう

transaction_start(); 

transaction_end(); 

など一切の呼び出しが代わりに

void bar() transaction_safe; 

のような関数指定子とブロック指定子の元を呼び出し、後者の厳格なルールに

transaction { /* body */ } 

のような、そして何がある存在しないことミックスインで使用できるように見えます。

これはどうすればできますか(、プリプロセッサを含むなし)?また、そのone of the main benefits of STM is composabilityに注意してください、しかしbarがトランザクション対応であることを反映するために、インスタンスを取得する方法はありませんようです。 2つの実装

template<typename F> 
void TransactionNone::run(F f) { f(); } 

と属性について

template<typename F> 
void TransactionReal::run(F f) { transaction{ f(); } } 

template<class Transaction> 
struct foo { 
    void bar() { 
     Transaction::run([](){ /* Do something. */ }); 
    } 
}; 

:同様に

答えて

1

は、ラムダと、あなたのような何かを行うことがありそうです

関数は、トランザクションが安全でない場合はトランザクションセーフです。

そのキーワードを省略して、コンパイラ/リンカにそのジョブをさせてくれるようです。

+0

感謝します。コードの残りの部分を「ラップする」ように 'ロックする 'ことは非常に賢いです。もう1つのポイントについては、「トランザクションセーフではない場合は関数はトランザクション安全です」というキーがキーです。あなたはおそらくそれのソースにリンクできますか?私はそれを見つけるように見えない。 –

+0

Doc N3919の「第5章取引に関する安全性」の第2冊。 – Jarod42

+0

もう一度多くのおかげです。最初の部分は、 'Locking'がコードをラップする部分です。 2番目の部分については、デフォルトが安全であることを指摘してくれてありがとうと思います(そして、それは高価ではないかもしれないと確信しています。しかし、特定の(おそらくはマイナーな)意味では、mixinがどのように関数が安全でないかコンパイラに示すことができるのかという疑問を投げ捨てるように見えます。しかし、大きな答え。 –