问题标签 [lockless]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
227 浏览

c - 如何评估无锁队列的性能?

我已经使用http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf中解释的危险指针方法实现了一个无锁队列,使用 GCC CAS 指令用于实现,pthread 本地存储用于线程本地结构。我现在正在尝试评估我编写的代码的性能,特别是我试图在此实现与使用锁(pthread 互斥锁)来保护队列的实现之间进行比较。
我在这里问这个问题是因为我尝试将它与“锁定”队列进行比较,我发现这在无锁实现方面具有更好的性能。我尝试的唯一测试是在 4 核 x86_64 机器上创建 4 个线程,在队列上执行 10.000.000 次随机操作,它比无锁版本快得多。

我想知道您是否可以建议我遵循的方法,即我必须在队列上测试什么样的操作以及我可以使用什么样的工具来查看我的无锁代码在哪里浪费时间。

我还想了解无锁队列的性能是否可能仅仅因为 4 个线程不足以看到重大改进......

谢谢

0 投票
3 回答
160 浏览

c - 我应该如何在不使用锁的情况下从另一个线程的回调中注册更新?

这是似乎属于“天真明显但可能是错误的”类别的问题之一。当然,我正在努力寻找一种适用于所有极端情况的解决方案。看来这一定是一直遇到的问题。

我有一个“硬件”线程和一个“处理”线程。

硬件线程在我无权访问的封闭二进制库中运行。

处理线程向硬件线程注册回调,以通知与硬件状态更改相关的某些(罕见)事件。

我希望能够通知处理线程中的事件循环状态已更改。我想这样做而不需要依赖外部库或以不可移植的方式,也不需要使用锁(因为我不知道硬件线程何时可能想要再次通知处理线程)。

所以,我目前关于如何解决这个问题的想法如下:

update很明显,如果曾经环绕并且恰好达到local_updatebefore processing_functionis next 调用的值(尽管几乎可以肯定我可以假设这永远不会发生),这将打破。

我在这里错过了一些微妙(或不那么微妙)的东西吗?

有没有更好的方法来解决整个问题?

可以假设回调只从一个线程(硬件线程)调用。

0 投票
3 回答
3375 浏览

c++ - 在 C++ 中将指针转换为 volatile void**

我有相当不错的 C++ 技能,但是这个演员给我带来了问题。我有一个接受以下参数的函数:(volatile void **, void * , void*). 我有 3 个int*变量,我试图将它们作为(&var1, var2, var3). 但是,我收到以下错误:Cannot convert parameter 1 from int** to volatile void**. 是否需要制作特定的演员表才能做到这一点?下面是我正在使用的代码片段。任何帮助是极大的赞赏。

这是在 Windows XP 机器上的 VS2010 中完成的。

0 投票
2 回答
495 浏览

thread-safety - 几乎无锁的生产者消费者

我有生产者消费者问题需要稍作修改来解决 - 有许多并行生产者,但一个并行线程中只有一个消费者。当生产者在缓冲区中没有位置时,它会简单地忽略元素(不等待消费者)。我已经写了一些 C 伪代码:

我不能 100% 确定这段代码是正确的。你能看到任何可能发生的问题吗?或者也许这段代码可以用更好的方式编写?

0 投票
3 回答
3829 浏览

c# - 实现无锁队列(用于 Logger 组件)

我正在设计一个新的改进的 Logger 组件(.NET 3.5,C#)。

我想使用无锁实现。

日志事件将从(可能)多个线程发送,尽管只有一个线程将实际输出到文件/其他存储介质。

本质上,所有的作者都*将他们的数据排入队列*,以便由其他进程(LogFileWriter)检索。

这可以以无锁的方式实现吗?我在网上找不到对这个特定问题的直接引用。

0 投票
1 回答
375 浏览

c - 使用 CAS(比较和交换)时,如何确保旧值实际上是旧的?

考虑以下:

我需要一种将 *target 读入局部变量的方法,并确保局部变量不会被优化为只是 *target。易失性是一个答案吗?

0 投票
2 回答
693 浏览

concurrency - Clojure 是否使用无锁算法实现无锁?

我的 Clojure 任务正在取得进展(在 4clojure.com 上解决了大约 80 个问题),我继续阅读和编码并尝试“得到它”。

现在我对 Clojure 被设计为“无锁并发”感到有点困惑。我对死锁非常了解(例如:“我编写的 Java 代码很糟糕,最终陷入死锁”,而不是“我是并发专家”)。我也读过这个:

为什么无锁并发如此重要(在 Clojure 中)?

我意识到 Clojure 程序不能死锁是多么的棒。

但我有点困惑:这样的壮举是通过在后台实现无锁算法实现的,还是使用了潜在的“可死锁”算法,但使用正确的实现保证永远不会死锁(这会以某种方式对 Clojure 程序员“隐藏” )?

最近有一个关于无锁算法的黑客新闻讨论:

http://news.ycombinator.com/item?id=4103921

参考1024cores.net上的以下“无锁算法”页面:

http://www.1024cores.net/home/lock-free-algorithms

我不明白这篇文章和 Clojure 下并发如何工作之间的关系。

这让我完全困惑:当我在 Clojure 中开发并发程序时,这是否意味着“锁和无锁算法”对我来说不是问题?

0 投票
1 回答
400 浏览

lockless - 无锁多读、单写链表

我一直在网上探索各种无锁/无锁链表的解决方案。我遇到了诸如 RCU、危险指针和辅助节点/“标记”节点上的出版物等技术来解决这个问题。它们都解决了多个作者和读者的并发问题。
在寻求任何这些解决方案之前,我想检查是否有任何更简单的标准技术来开发无锁算法,用于单写 - 多读链表。(支持的操作是添加、删除、查找和更新)

谢谢你的时间。斯里兰卡

0 投票
2 回答
6660 浏览

c++ - 如何在 C++ 中使用无锁循环缓冲区实现零拷贝 tcp

我有多个线程需要使用 TCP 流中的数据。我希望使用共享内存中的循环缓冲区/队列从 TCP 套接字读取。TCP 接收将直接写入循环队列。消费者将从队列中读取。

这种设计应该能够实现零拷贝和零锁定。但是这里有两个不同的问题。

  1. 从 TCP 套接字中仅读取 1 条逻辑消息是否可能/有效?如果没有,并且我阅读了超过 1 条消息,我将不得不将残差从 this 复制到 this->next。

  2. 真的可以实现无锁队列吗?我知道有原子操作,但这些也可能很昂贵。因为所有的 CPU 缓存都需要失效。这将影响我所有 24 个内核上的所有操作。

我对低级 TCP 有点生疏,并且不清楚如何判断消息何时完成。我是在寻找 \0 还是特定于实现?

0 投票
3 回答
806 浏览

c# - 线程安全的通用字段

我有一个通用字段和一个封装它的属性:

问题是这个属性可以从一个线程写入并同时从多个线程读取。如果Tstruct, or long, 读者可能会得到部分旧值和部分新值的结果。我怎样才能防止这种情况?

我尝试使用volatile,但这是不可能的:

volatile 字段不能是“T”类型。

由于这是我已经编写的代码的一个更简单的例子,它使用ConcurrentQueue<T>,所以我也考虑在这里使用它:

这会起作用,但在我看来,对于应该简单的事情来说,它是过于复杂的解决方案。

性能很重要,因此,如果可能,应避免锁定。

如果 aset与 同时发生get,我不在乎get返回旧值还是新值。