标签: lock-free

无锁多线程适用于真正的线程专家

我正在阅读Jon Skeet给出一个问题的答案,并在其中提到了这一点:

就我而言,无锁多线程是真正的线程专家,其中我不是一个.

这不是我第一次听到这个,但是如果你有兴趣学习如何编写无锁多线程代码,我发现很少有人在谈论你如何实际做到这一点.

所以我的问题是除了学习关于线程的所有内容之外,等等你在哪里开始尝试学习专门编写无锁多线程代码以及什么是好资源.

干杯

.net c# multithreading lock-free

85
推荐指数
4
解决办法
2万
查看次数

原子操作成本

原子操作的成本是什么(比较和交换或原子添加/减少中的任何一个)?它消耗了多少周期?它会暂停SMP或NUMA上的其他处理器,还是会阻止内存访问?它会在无序CPU中刷新重新排序缓冲区吗?

缓存有什么影响?

我对现代流行的CPU感兴趣:x86,x86_64,PowerPC,SPARC,Itanium.

performance atomic cpu-architecture lock-free

79
推荐指数
3
解决办法
3万
查看次数

在C++中是否有生产就绪的无锁队列或散列实现

我一直在谷歌搜索C++中的无锁队列.我发现了一些代码和一些试验 - 但我没有能够编译.也欢迎无锁哈希.

摘要:到目前为止,我没有正面答案.没有"生产就绪"库,令人惊讶的是现有的库都没有符合STL容器的API.

c++ stl lock-free

77
推荐指数
9
解决办法
4万
查看次数

圆形无锁缓冲区

我正在设计一个连接到一个或多个数据源流的系统,并对数据进行一些分析,而不是基于结果触发事件.在典型的多线程生产者/消费者设置中,我将有多个生产者线程将数据放入队列,并且多个消费者线程读取数据,并且消费者仅对最新数据点加上n个点感兴趣.如果慢速消费者无法跟上,生产者线程将不得不阻止,当然,当没有未经处理的更新时,消费者线程将被阻止.使用具有读取器/写入器锁的典型并发队列将很好地工作,但是进入的数据速率可能很大,因此我希望减少锁定开销,尤其是生产者的写入锁.我认为我需要一个循环无锁缓冲区.

现在有两个问题:

  1. 圆形无锁缓冲是答案吗?

  2. 如果是这样,在我自己推出之前,您是否知道任何符合我需求的公共实施?

任何指向实现循环无锁缓冲区的指针总是受欢迎的.

顺便说一句,在Linux上用C++做这件事.

一些额外的信息:

响应时间对我的系统至关重要.理想情况下,消费者线程会希望尽快看到任何更新,因为额外的1毫秒延迟可能会使系统失去价值,或者价值更低.

我倾向于的设计思想是一个半无锁的循环缓冲区,生产者线程尽可能快地将数据放入缓冲区,让我们调用缓冲区A的头部,除非缓冲区已满,否则A满足缓冲区Z的结束.消费者线程将各自保存两个指向循环缓冲区P和P n的指针,其中P是线程的本地缓冲区头,P n是P 之后的第n个项目.每个消费者线程将推进其P和P ñ一旦处理完当前P和缓冲器指针Z的端前进具有最慢P ñ.当P赶上A,这意味着没有更新的处理更新,消费者旋转并忙着等待A再次前进.如果消费者线程旋转太长时间,它可以进入休眠状态并等待条件变量,但我没关系消费者占用CPU周期等待更新,因为这不会增加我的延迟(我会有更多的CPU核心)比线程).想象一下,你有一个循环轨道,并且生产者正在一群消费者面前运行,关键是调整系统,使生产者通常比消费者领先一步,并且大部分操作都可以使用无锁技术完成.我理解获得正确实施的细节并不容易......好吧,非常难,这就是为什么我想在自己制作一些错误之前先从别人的错误中吸取教训.

c++ algorithm concurrency multithreading lock-free

69
推荐指数
8
解决办法
5万
查看次数

无锁算法真的比锁定完全算法表现更好吗?

Raymond Chen一直在做一个关于无算法大型 系列 .除了函数的简单情况之外,似乎所有这些的主流模式是它们实现自己的锁.当然,没有处理器锁,但是在每个CPU上反复循环以确保一致性的概念非常类似于自旋锁.作为一个自旋锁,它们的效率将低于操作系统附带的一般锁,因为它们在等待其他线程时不会控制其量子.因此,每当有人来找我并说"但我的算法是无锁的"时,我的一般反应是"如此"? InterlockedXxx

我很好奇 - 是否有可用的基准测试显示无锁算法比其完全锁定的算法有优势?

multithreading synchronization lock-free

45
推荐指数
5
解决办法
9064
查看次数

无锁同步总是优于使用锁的同步吗?

在 C++ 中,有一种原子类型std::atomic<T>。该原子类型可能是无锁的,也可能不是,具体取决于类型 T 和当前平台。如果某个类型的无锁实现在类型 T 的平台上可用,那么大多数编译器都会提供无锁atomic<T>。在这种情况下,即使我想要非无锁atomic<T>我也无法拥有它。

C++ 标准决定只保留一个,std::atomic<T>而不是一std::atomic<T>加一std::lock_free<T>(部分针对特定类型实现)。这是否意味着“在任何情况下,当后者可用时,使用非无锁原子类型都会比使用无锁原子类型更好”?(主要是在性能方面而不是易用性方面)。

c++ synchronization lock-free stdatomic

45
推荐指数
4
解决办法
8227
查看次数

使用Boost.Lockfree队列比使用互斥锁慢

直到现在我std::queue在我的项目中使用.我测量了此队列上特定操作所需的平均时间.

在两台机器上测量时间:我的本地Ubuntu VM和远程服务器.使用时std::queue,两台机器的平均值几乎相同:约750微秒.

然后我"升级" std::queueboost::lockfree::spsc_queue,所以我可以摆脱保护队列的互斥锁.在我的本地虚拟机上,我可以看到巨大的性能提升,平均现在是200微秒.然而,在远程机器上,平均值高达800微秒,这比以前慢了.

首先我认为这可能是因为远程机器可能不支持无锁实现:

Boost.Lockfree页面:

并非所有硬件都支持同一组原子指令.如果硬件不可用,则可以使用防护装置在软件中进行仿真.然而,这具有失去无锁属性的明显缺点.

要确定是否支持这些指令,请boost::lockfree::queue调用一个方法bool is_lock_free(void) const;.但是,boost::lockfree::spsc_queue没有这样的功能,对我来说,这意味着它不依赖于硬件而且总是无锁 - 在任何机器上.

性能损失的原因是什么?


例子(生产者/消费者)

// c++11 compiler and boost library required

#include <iostream>
#include <cstdlib>
#include <chrono>
#include <async>
#include <thread>
/* Using blocking queue:
 * #include <mutex>
 * #include <queue>
 */
#include <boost/lockfree/spsc_queue.hpp>


boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024>> queue;

/* Using blocking queue:
 * std::queue<int> queue;
 * std::mutex mutex;
 */

int main()
{
    auto producer = std::async(std::launch::async, …
Run Code Online (Sandbox Code Playgroud)

c++ performance multithreading boost lock-free

42
推荐指数
1
解决办法
1万
查看次数

您是否可以通过保证多个线程不能访问同一内存来避免锁定?

假设我有一个大型数组,我想用多个线程处理内容.如果我将每个线程委托给特定的部分,保证不重叠,这是否消除了锁定的需要,假设线程不访问数组外的任何其他内存?

像这样的东西(伪代码):

global array[9000000];

do_something(chunk) {
    for (i = chunk.start; i < chunk.end; i++)
        //do something with array
}

main() {
    chunk1 = {start: 0, end: 5000000};
    chunk2 = {start: 5000000, end: 9000000};

    start_thread(thread1, do_something(chunk1));
    start_thread(thread2, do_something(chunk2));

    wait_for_join(thread1);
    wait_for_join(thread2);
    //do something else with the altered array
}
Run Code Online (Sandbox Code Playgroud)

c c++ multithreading lock-free

41
推荐指数
3
解决办法
2194
查看次数

两个unique_ptr <T>的无锁交换

交换两个unique_ptrs并不保证是线程安全的.

std::unique_ptr<T> a, b;
std::swap(a, b); // not threadsafe
Run Code Online (Sandbox Code Playgroud)

由于我需要原子指针交换,因为我喜欢所有权处理unique_ptr,是否有一种简单的方法将它们组合起来?


编辑:如果这是不可能的,我愿意接受替代方案.我至少想做这样的事情:

threadshared_unique_ptr<T> global;

void f() {
   threadlocal_unique_ptr<T> local(new T(...));
   local.swap_content(global); // atomically for global
}
Run Code Online (Sandbox Code Playgroud)

在C++ 11中这样做的惯用方法是什么?

c++ lock-free unique-ptr atomic-swap c++11

38
推荐指数
2
解决办法
9808
查看次数

如何编写无锁结构?

在我的多线程应用程序中,我看到其中存在严重的锁争用,从而阻碍了跨多个核的良好可伸缩性.我决定使用无锁编程来解决这个问题.

如何编写无锁结构?

multithreading multicore lock-free

36
推荐指数
8
解决办法
9848
查看次数