软件事务内存友好的通用组件

时间:2016-08-09 19:20:16

标签: c++ transactional-memory template-mixins

假设我们写了一些可以同时使用的新类。显然,我们不希望锁定所有可能同时被调用的东西。解决此问题的一种方法是通过mixins参数化指定锁定:

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

并使用实际锁定多线程情况的类来实例化Locking,并使用对其他情况执行no-ops的类(希望编译器甚至可以优化掉调用)。

现在假设我想用软件事务内存而不是锁定来做这件事。看N3919(或gcc precursor),这个想法是不同的。没有诸如

之类的电话
transaction_start();

transaction_end();

而是有像

这样的函数说明符
void bar() transaction_safe;

和块说明符,如

transaction { /* body */ }

后者的严格规则称之为前者,mixins可以使用任何类似的内容。

如何做到这一点(没有涉及预处理器)?另请注意one of the main benefits of STM is composability,但似乎没有办法让实例化反映出bar是可交易的。

1 个答案:

答案 0 :(得分:1)

以类似的方式,使用lambda,您似乎可以执行以下操作:

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

有两个实现

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

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

对于属性,

  

如果函数不是事务不安全的,则该函数是事务安全的。

所以你似乎可以省略那个关键字,让编译器/链接器完成这项工作。