多线程编程指南

数据锁定

数据锁定可保证一直维护对数据集合的访问。对于数据锁定,代码锁定概念仍然存在,但代码锁定只是对共享(全局)数据的轮流引用。对于互斥锁,在每个数据集合的临界段中只能有一个线程。

另外,在多个读取器、单个写入器协议中,允许每个数据集合或一个写入器具有多个读取器。当多个线程对不同数据集合执行操作时,这些线程可以在单个模块中执行。需要特别指出的是,对于多个读取器、单个写入器协议,这些线程不会在单个集合上发生冲突。因此,数据锁定通常比代码锁定具备的并发性更多。

使用锁定时应使用哪种策略,在程序中实现互斥、条件变量还是信号?是要尝试通过仅在必要时锁定并在不必要时尽快解除锁定来实现最大并行性(这种方法称作“细粒度锁定 (fine-grained locking)”)?还是要长期持有锁定,以使使用和释放锁的开销降到最低程度(这种方法称作“粗粒度锁定 (coarse-grained locking)”)?

锁定的粒度取决于锁定所保护的数据量。粒度非常粗的锁定可能是单一锁定,目的是保护所有数据。划分由适当数目的锁定保护数据的方式非常重要。锁定粒度过细可能会降低性能。当应用程序包含太多锁定时,与获取和释放锁关联的开销可能会变得非常大。

常见的明智之举是先使用粗粒度方法,确定瓶颈,并在必要时添加细粒度锁定来缓解瓶颈。此方法听起来是很合理的建议,但是您应该自行判断如何在最大化并行性与最小化锁定开销之间找到平衡。