【问题标题】:How to synchronize access to an index of an array如何同步访问数组的索引
【发布时间】:2019-09-29 19:11:21
【问题描述】:

我正在编写两个模拟银行服务的程序。有服务器程序和用户程序。服务器设置多个线程,这些线程充当“电子计数器”,读取用户的请求并按他们说的做。

用户的帐户存储在一个数组内的服务器上,可以根据请求访问它们。我的问题如下:假设线程 A 正在将钱从 John 转移到 Maria。如何在交易进行时阻止其他线程访问 John 和 Maria 的帐户?我知道信号量、互斥体和条件变量,但是我找不到一种方法来使用它们,并且不会阻止对整个数组的访问。

编辑:我被告知要创建 N 个互斥体,其中 N = 帐户数,并且每个互斥体都与一个帐户相关联。有没有更好的办法来解决这个问题?

【问题讨论】:

  • 提示 - 互斥量和信号量。运行将保存并处理所有排除项的中间进程。您还可以将互斥锁与数组元素关联
  • @P__J__ “运行将保存并处理所有排除项的中间过程”是什么意思?你能详细说明一下吗?

标签: c multithreading synchronization pthreads


【解决方案1】:

有几个选项,其中:

选项 1

为每个帐户提供自己的互斥锁。确保当一个线程想要锁定两条记录时(例如,对于传输),它始终以相同的顺序查看它们——例如首先是最小的数字。

然后线程将简单地获取它们需要修改的记录的互斥体(始终遵守正确的锁定顺序以避免死锁),进行修改,然后释放互斥体。

选项 2

滚动您自己的记录级锁。为每个帐户建立一个变量,记录该帐户是否被锁定。这可以在帐户数组中或在单独的数据结构中。使用单个互斥锁来保护对所有锁标志的访问,并使用 CV 来帮助线程等待锁可用。

线程然后以这种模式运行:

  1. 锁定互斥体。
  2. 如果所有必需的记录均已解锁,则打开其锁定标志并转到第 4 步。
  3. 等待简历,然后返回第 2 步。
  4. 释放互斥锁
  5. 执行所有(其他)帐户修改
  6. 重新锁定互斥锁
  7. 关闭步骤 2 中获取的所有记录锁。
  8. 广播到 CV 并释放互斥锁。

选项 2 比选项 1 有更多的线程争用,因此在实践中可能会更少并发,但这是仅使用一个互斥体所涉及的权衡。您可以通过混合解决方案在一定程度上解决这个问题,该解决方案将帐户分成组,并在每个组的基础上实施选项 2。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-25
    • 1970-01-01
    • 2013-09-27
    • 2023-03-12
    • 2011-12-24
    • 1970-01-01
    • 2018-07-05
    • 2011-03-07
    相关资源
    最近更新 更多