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

Generic Components Friendly To Software Transactional Memory

假设我们写了一些新的 class 可以同时使用也可以不使用。显然,我们不想锁定所有的东西,因为它们有可能被并发调用。解决此问题的一种方法是通过 mixins 指定锁定进行参数化:

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

并使用 class 实例化 Locking 实际锁定多线程情况,并使用 class 对其他情况不执行任何操作(希望编译器会甚至优化调用)。

现在假设我想用软件事务内存而不是锁定来做到这一点。看N3919 (or the gcc precursor),思路就不一样了。没有

这样的调用
transaction_start();

transaction_end();

取而代之的是像

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

和像

这样的块说明符
transaction { /* body */ }

有严格的后者调用前者的规则,任何看起来像它的东西都不能被 mixin 使用。

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

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

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

有 2 个实现

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

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

对于属性,

A function is transaction-safe if it is not transaction-unsafe.

看来您可以省略该关键字,让 compiler/linker 完成这项工作。