事务内存
事务内存起源于数据库理论,提供了一种替代进程同步的策略。
内存事务是原子性的,是一系列内存读写操作。如果事务中的所有操作都已完成,则内存事务被提交。否则,必须中止并回滚这些操作。可以通过添加到编程语言中的功能获得事务内存的便利性。考虑一个例子。假设我们有一个修改共享数据的函数 update()。传统上,此函数将使用互斥锁(或信号量)编写,如下所示:
void update (){ acquire(); /* modify shared data */ release(); }
但是,使用互斥锁和信号量等同步机制会涉及许多潜在的问题,包括死锁。此外,随着线程数量的增加,传统的锁定扩展性较差,因为线程之间争夺锁所有权的竞争级别变得非常高。作为传统锁定方法的替代方案,可以向编程语言添加利用事务内存的新功能。在我们的示例中,假设我们添加了构造 atomic{S},它确保 S 中的操作作为事务执行。这允许我们如下重写 update() 函数:
void update (){ atomic { /* modify shared data */ } }
使用这种机制而不是锁的优势在于,事务内存系统(而不是开发人员)负责保证原子性。此外,由于不涉及锁,因此不可能发生死锁。此外,事务内存系统可以识别 atomic 块中哪些语句可以并发执行,例如对共享变量的并发读取访问。当然,程序员可以识别这些情况并使用读写锁,但是随着应用程序中线程数量的增加,此任务变得越来越困难。事务内存可以在软件或硬件中实现。软件事务内存 (STM) 完全在软件中实现事务内存 - 不需要特殊的硬件。它通过在事务块内插入检测代码来工作。代码由编译器插入,并通过检查语句可以在哪里并发运行以及在哪里需要特定的低级锁定来管理每个事务。硬件事务内存 (HTM) 使用硬件缓存层次结构和缓存一致性协议来管理和解决涉及驻留在不同处理器缓存中的共享数据的冲突。它不需要特殊的代码检测,因此比 STM 的开销更小。但是,HTM 确实要求修改现有的缓存层次结构和缓存一致性协议以支持事务内存。事务内存已经存在数年,但尚未得到广泛实施。然而,多核系统的增长以及与之相关的对并发和并行编程的重视,促使学术界和商业软件和硬件供应商在这一领域进行了大量的研究。