【问题标题】:Avoid Frequent Locking避免频繁锁定
【发布时间】:2013-07-22 17:26:02
【问题描述】:

我的程序从交换中获取了大量数据。数据被解析为刻度对象。典型的滴答声

struct Tick
{
    string ID;
    int bidprice[5];
    int askprice[5];
    int totalTradedQuantity;
    int totalTradedVolume;
    .....
    .....
}

此刻度对象已发布到网络并记录在文件中。目前我正在锁定更新tick和发布。

Parser Part:
lock();
tick update
unlock();

Publisher Part:
lock();
tick publish;
unlock();

由于数据的频率很高(每秒 5000 个),我必须为收到的每个数据锁定。会不会导致性能问题?如何避免占用这么多锁。任何人都可以建议具有最少锁定的设计实现。请帮忙。

【问题讨论】:

  • 我认为它需要锁定机制。我没有看到任何减少它的选择。如果我没有错,您在内部使用互斥锁机制。如果是这种情况,请使用 try-lock 功能。它至少不会阻塞线程。
  • “tick update”和“tick publish”究竟包含什么。如果您所做的只是将已经准备好的数据复制到某种列表中,那还不错。如果涉及大量工作,那么或许你应该考虑是否可以将部分工作“移出”锁,所以只有最后一步“将数据复制到列表中”。同样对于“tick publish”,仅在您从列表中提取数据时锁定 - 一旦您有一个单独的数据项,您就可以释放锁定。
  • 该问题没有关于更新和发布过程的足够信息。它们是否在共享 Tick 实例的单独进程/线程中运行?
  • 一个无争议的锁在普通硬件上大约需要 50 纳秒,大概。所以这大约是每秒 0.05% 的开销。哪里来的牛肉?您只是猜测还是实际测量过
  • 每秒 5000 个还不错。以每秒 500,000 的速度,您需要无锁数据结构。

标签: c++ multithreading locking


【解决方案1】:

锁定或信号量是防止竞争条件的唯一工具。

信号量将防止忙等待。但是锁(特别是自旋锁)会导致忙等待。 (在你的情况下,数据频率很高;你不应该担心忙等待。)

但是,CPU 部署了非常高效和快速的锁定机制。在这种情况下,您不必担心锁定和解锁开销。

此外,您始终可以选择将请求排队并在锁定和解锁部分进行处理。

【讨论】:

  • 你说的是哪个操作系统,信号量在哪里忙着等待——我知道的四个(Linux(以及其他版本的 Unix)、Windows、OSE 和 Symbian)做一个适当的“让这个线程/process 等到信号量空闲”。在这些操作系统中,只有自旋锁忙于等待。
【解决方案2】:

因为您需要互斥,所以您需要锁定。您当前的设计可以做的最好的事情就是使用不寻常的锁。例如,如果你读的比写的多,你可以使用读/写锁。如果线程之间的争用很少,并且同一线程通常会连续多次需要锁,那么您可能会从偏向锁中获得性能提升。

但是,我怀疑您最好的选择是重新设计。我最喜欢的书是Is Parallel Programming Hard, and, If So, What Can You Do About It?。我读过的所有其他并行编程书籍都展示了如何使线程进行通信(例如,通过锁)。这本书展示了如何设计线程可以独立运行而无需通信(尤其是无需通过锁进行协调)。

【讨论】:

    【解决方案3】:

    拿锁也不错。锁争用很糟糕。你有几把锁?每个刻度一个,每个 ID 一个,总共一个?通常最简单的解决方案是避免使用单个集中锁。

    【讨论】:

      猜你喜欢
      • 2012-11-13
      • 2012-03-30
      • 1970-01-01
      • 2016-04-29
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多