草庐IT

c++ - 具有细粒度锁的线程安全链表

coder 2023-06-22 原文

在一个程序中,我有一个 M 类:

class M{
    /*
      very big immutable fields
    */
    int status;
};

我需要一个 M 类型对象的链表。

三种类型的线程正在访问列表:

  • 生产者:生产对象并将其附加到列表的末尾。所有新生成的对象的状态都为 NEW。 (运算时间 = O(1))
  • 消费者:消费列表开头的对象。如果对象的状态=CONSUMER_ID,则对象可以被消费者消费。每个消费者都保留链表中它可以消费的第一个项目,因此消费是(摊销?)O(1)(见下面的注释)。
  • 析构函数:当有通知表明对象已被正确使用时删除已使用的对象(操作时间 = O(1))。
  • 修饰符:根据状态图更改对象的状态。任何对象的最终状态都是消费者的 ID(每个对象的操作时间 = O(1))。

消费者的数量少于 10 个。生产者的数量可能有几百个。有一个修饰符。

注意:修饰符可能会修改已经消费的对象,因此消费者存储的元素可能会来回移动。对于这个问题,我没有找到更好的解决方案(虽然对象之间的比较是 O(1),但操作不再摊销 O(1))。

性能非常重要。因此,我想使用原子操作或细粒度锁(每个对象一个)来避免不必要的阻塞。

我的问题是:

  1. 首选原子操作,因为它们更轻量。我想我必须使用锁来更新析构线程中的指针,我可以使用原子操作来处理其他线程之间的争用。请让我知道我是否遗漏了什么,并且有一个原因我不能在状态字段上使用原子操作。

  2. 我想我不能使用 STL 列表,因为它不支持细粒度锁。但是您会推荐使用 Boost::Intrusive 列表(而不是自己编写)吗? Here有人提到侵入式数据结构更难实现线程安全?这对细粒度锁来说是正确的吗?

  3. 生产者、消费者和析构函数将基于某些事件被异步调用(我打算使用 Boost::asio。但我不知道如何运行修饰符以最小化它与其他线程的争用。选项是:

    • 与生产者异步。
    • 与消费者异步。
    • 使用自己的计时器。

只有在满足某些条件的情况下,任何此类调用才会对列表进行操作。我自己的直觉是,我如何调用修饰符之间没有区别。我错过了什么吗?

我的系统是 Linux/GCC,我使用的是 boost 1.47 以防万一。

类似问题:Thread-safe deletion of a linked list node, using the fine-grained approach

最佳答案

The performance is very important. Therefore, I want to use atomic operations or fine-grained locks (one per object) to avoid unnecessary blocking.

这会增加竞争线程(访问相同数据)在不同内核上同时运行的可能性,从而使性能变差。如果锁太细,线程可能会争用(它们的缓存之间的乒乓数据)并以缓慢的锁步运行而不会阻塞锁,从而导致糟糕的性能。

您希望使用足够粗的锁,以便争用同一数据 block 的线程尽快彼此阻塞。这将迫使调度程序调度非竞争线程,消除破坏性能的缓存乒乓。

您有一个常见的误解,认为阻塞是不好的。事实上,争用是不好的,因为它会将内核减慢到总线速度。阻塞结束争用。阻塞很好,因为它取消了竞争线程的调度,从而允许调度非竞争线程(可以全速并发运行)。

关于c++ - 具有细粒度锁的线程安全链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7935738/

有关c++ - 具有细粒度锁的线程安全链表的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby - 如何使用 Ruby aws/s3 Gem 生成安全 URL 以从 s3 下载文件 - 2

    我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A

  4. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  5. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  6. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  7. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  9. ruby - 如何让Ruby捕获线程中的语法错误 - 2

    我正在尝试使用ruby​​编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?

  10. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

随机推荐