August 2021
Intermediate to advanced
450 pages
5h 35m
Chinese
有时任务之间需要共享数据。在此情况下,数据访问就必须进行同步,使得在同一时刻至多有一个任务能访问数据。有经验的程序员可能认为这将问题简单化了(例如,很多任务同时读取不变的数据是没有任何问题的),但请考虑如何确保在同一时刻至多有一个任务可以访问一组给定的对象。
此问题解决方法的基础是“互斥对象”mutex。一个thread使用lock()操作来获取一个互斥对象:
lck的类型被推断为scoped_lock<mutex>(参见6.2.3节)。scoped_lock的构造函数获取了互斥对象(通过调用m.lock())。如果另一个线程已经获取了互斥对象,则当前线程会等待(“阻塞”)直至那个线程完成对共享数据的访问。一旦线程完成了对共享数据的访问,Scoped_lock会释放mutex(通过调用m.unlock())。当一个mutex被释放,等待此mutex的thread会恢复执行(“被唤醒”)。互斥和锁机制在头文件<mutex>中提供。
注意RAII(参见5.3节)的使用。使用scoped_lock和unique_lock(参见15.6节)这样的资源句柄比显式对mutex加锁、解锁要更简单且更安全。
共享数据和mutex之间是一种常规的对应关系:程序员必须知道哪个mutex对应哪个数据。显然,这很容易出错,我们应努力借助多种语言特性来使这种对应关系更为清晰。例如:
对于一个名为rec的Record,不难猜测:rec.rm是一个mutex,你在访问rec其他数据前应获取这个互斥对象。可见,通过注释或好的命名方式可以提高程序的可读性。 ...
Read now
Unlock full access