并发访问对象组

时间:2011-08-01 22:10:24

标签: concurrency scheduled-tasks scheduling mutual-exclusion

我正在尝试开发一个由线程池组成的应用程序,使用工作窃取算法来并发执行任务。

这些任务

  • 访问一组预定义的对象;
  • 必须“原子地”获取它在实际运行之前访问的所有对象的读/写权限;
  • 完成后(并保证最终完成)释放他们获得的物品。

解决此问题的一种可能方法是让每个线程一次接收任务,然后尝试使用预定义的顺序锁定每个对象。如果至少有一个失败,则释放所有锁,然后继续执行另一个任务。

然而,这种方法会增加具有大对象依赖性的任务的饥饿概率,甚至可能会导致实时锁定。

是否有另一种方法可以在最大化并发性的同时获取一组锁? (没有全局锁定)或者可能以不再需要的方式更改系统? 如果是的话,有关它的任何好文章吗?

ps:正如thiton回答的那样,这是“餐饮哲学家”问题的概括版本。我正在寻找非集中式解决方案,特别是在高负载(添加和删除任务)方面表现良好的算法。

3 个答案:

答案 0 :(得分:1)

订购资源是一种有效的方法。想到的另一个直接的方法是引入一个共享仲裁器,其中包含有关资源可用性的信息。任务将在单个原子步骤“获取(r1,r2,...,rn)”中通过仲裁器锁定所需的所有资源,并以“release(r1,r2,...,rn)”类似地释放它们。

如果可以满足“获取”请求A,仲裁者将确保在A释放它们之前,任何其他任务都不会获得A持有的任何资源。

仲裁者可以使用多种策略来满足传入请求:

  1. 拒绝无法立即满足的请求 - 任务必须重新尝试。这为活锁和饥饿打开了大门。
  2. 将所有传入的请求保留在队列中,并以FIFO方式为其提供服务,因为头部请求所需的资源可用。
  3. 将所有未满足的请求保留在列表中(不阻止其所需资源)并在每次释放某些资源时迭代它们(可能优先考虑旧请求),以找到可以满足的请求。

答案 1 :(得分:0)

如果一个任务试图锁定对象只在某个时刻失败,那么另一个任务可能无法锁定一个对象,因为当时第一个任务拥有它。

我想我最初尝试获取锁时会使用全局锁,也可能在最终释放它们时使用全局锁。

当一个简单的解决方案在实践中被证明不足时,我担心最大并发性。

答案 2 :(得分:0)

您的问题称为Dining Philosophers。您应该在此关键字下找到所需的任何文献数量: - )。