如何在 C++ 中管理需要从资源池访问两个不同资源的线程的线程同步

问题描述 投票:0回答:1

该程序模拟多个线程访问不同的资源。 我有一个资源池,在我的例子中是一组布尔值:

bool res[6] = {1, 1, 1, 1, 1, 1};
我还创建了 6 个不同的线程,它们都需要一次访问其中两个资源:

T1 -> needs res[0] and res[1]
T2 -> needs res[1] and res[2]
T3 -> needs res[2] and res[3]
T4 -> needs res[3] and res[4]
T5 -> needs res[4] and res[5]
T6 -> needs res[0] and res[5]

当线程使用资源时,它会将 bool 设置为 0,并在完成后返回到 1。例如:T1 将 res[0] 和 res[1] 设置为 0,“使用它”,然后将两者设置回 1。

我不确定如何使用互斥体或信号量来防止竞争条件。

明显但缓慢的方法是,当线程使用两个资源时使用互斥体锁定整个部分,并在完成后解锁它,以防止任何其他线程占用任何资源。问题是有些线程应该能够同时运行,例如:T1 和 T3 不共享资源,因此应该能够同时执行这些操作。另一方面,T1 和 T2 不应该能够同时运行,因为它们共享 res[1]。如有任何帮助,我们将不胜感激!

c++ multithreading synchronization thread-safety
1个回答
0
投票

理想的解决方案取决于资源的性质,但可以使用信号量或互斥量,并且速度将更多地取决于实现。

我建议使用互斥锁,因为听起来每个资源都是唯一的,每个线程都需要等待特定的资源。每个资源都需要自己的互斥体来控制线程对其的访问。这样就不需要锁定其他线程,除非他们想使用该特定资源。

例如:线程 1 正在使用资源 1,因此它将锁定资源 1 的互斥体。如果任何其他线程想要使用资源 1,则必须检查互斥体以查看其是否正在使用,然后等待互斥体解锁由使用它的线程(在本例中为线程 1)。

此外,如果您可以保证对它的原子访问(即没有竞争条件),您所描述的 res 布尔值在理论上是一个信号量。 有关原子访问的更多信息,请参阅此处。如果每个资源不是唯一的,意味着一个线程一次只需要 2 个资源,那么信号量方法可能会更好。

我建议在尝试制作这个模拟器之前,对多线程进行更多研究,并查看现有的解决方案,例如用于 C++ 的pthreads

© www.soinside.com 2019 - 2024. All rights reserved.