并发数据结构-1.4 池

简介:

原文链接译文链接,译者:huavben,校对:周可人

实现高效并发栈和队列的大部分挑战来自于一个被插入的元素可以被删除这一需求。并发池是一种支持插入和删除操作的数据结构,它允许删除操作移除任何一个已经被插入的,并且没有在随后被删除的元素。这样的弱需求提供了提高并发性能的机会。

一个高效的并发池可以使用任意静态一致的计数器来构建。在这样的并发池中,元素被置于数组当中,fetch-and-inc操作决定插入操作在哪个位置存储元素,同样的,fetch-and-inc操作决定删除操作在哪个位置获得元素。每一个数组元素都包含了一个表示满/空的比特位或者等效的机制,来表明在相应的位置,将要删除的元素已经存在。在这种策略下,使用combining tree,combining funnel,counting network,diffracting tree中的任何一个技术都可以并行化共享技术器,解决这一主要的瓶颈来创建出一个高吞吐量的共享并发池。此外,一个类似栈的池可以使用一个允许增加和减少操作的计数器来实现,然后利用以上技术中的一种来并行化.

最后,在前文中说讨论的消除技术(elimination technique)可以使用在利用combining tree,combining funnel,counting network,diffracting tree等技术实现的并发池中:假如在树中插入和删除操作相遇,那么删除操作可以获取插入操作插入的值,之后两个操作就不用继续遍历这个结构树。这项技术在高负载下能表现出良好的高性能.

上述的这些实现的缺点是,它们在低复杂的情况下性能糟糕。而且,在做负载分布工作的时候,这些实现并不允许我们如同那些专门为负载分布设计的池一样,得到具体的位置信息。

负载均衡算法涉及到一个任务池集合,每个任务池中有一些工作单元,其中每一个任务池都被本地化到一个处理器上。当线程创建了工作项之后就把它们置于本地化的任务池中,依靠负载均衡算法确保任务池中的工作数量都是均衡的。这样就避免了其他处理器仍然忙碌于自己工作的时候,有些处理器却处于空闲状态。大体上有两种解决这类问题的算法:工作共享(work sharing )和工作窃取(work stealing )。在工作共享方案中,每一个处理器尝试不断地将自身任务池中的工作卸下,放到其他任务池中。在工作窃取模式下,一个线程已经完成了自己的工作后就会去窃取其他任务池中的工作去执行。两种方案通过随机选择任务池来平衡工作或窃取工作。

传统工作窃取技术是Arara等人提出的,它基于一个无锁结构的双向队列。该双向队列只允许一个线程(该任务池的本地线程)在队列的一端进行操作,在另一端只允许弹出操作,并且允许在这一端的并发弹出操作在线程相互干扰的情况下中止。在这样的约束下,双向队列适合于任务窃取,并且这种约束允许一种简单的实现方式,即本地线程用低开销的load and store操作来进行插入和删除,只有当它和其他非本地删除线程竞争队列里的最后一个任务的时候,才会依赖昂贵的CAS操作。

在一些案例中已经清晰表明一次窃取多个任务的效果是令人满意的。一个非阻塞的多任务窃取算法由Hendler与Shavit在PODC(2002)上提出。在一些案例中同样表明通过使用 同类工作项信息来决定窃取那些工作是可取的。另外在SPAA(2000)上,Acar等人提出了一种位置引导(locality-guided)的窃取算法. 

目录
相关文章
|
监控 API C#
C#多线程(5):资源池限制
C#多线程(5):资源池限制
228 0
C#多线程(5):资源池限制
|
安全 算法 Java
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
141 0
【基础篇】7 # 队列:队列在线程池等有限资源池中的应用
|
7月前
分析一个简单的goroutine资源池
分析一个简单的goroutine资源池
46 0
|
10月前
|
Java Linux 调度
linux线程池浅谈
linux线程池浅谈
128 2
|
存储 缓存 监控
Android线程池原理详解
Android四种线程池原理
260 0
|
Java 安全 测试技术
线程同步方法和差别~(高并发中多个线程访问统一资源域,容易出现线程安全性)
同步就是指一个线程要等待上一个线程执行完之后才开始执行当前的线程; 异步是指一个线程去执行,它的下一个线程不必等待它执行完就开始执行。 同步优势:java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突, 因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性(保证线程安
2516 0
|
Java
多线程访问共同资源(队列,多线程,锁机制)
模拟场景:main方法为网络请求线程(也叫生产者线程),在网络请求线程中开启四个线程(消费者线程),进行高效处理队列中的共同资源(生产者线程生产的共同资源),等待资源处理完毕,网络请求线程执行结束,响应客户端。
824 0
|
缓存 NoSQL Java
源码梳理——Jedis从缓存池中获取资源和销毁资源
本文分析了jedis从缓存池中获取资源和销毁资源这一模块的源码
1883 0
|
Java 程序员 Go
grpool goroutine池详解 | 协程管理
goroutine协程非常轻量级,这也是为什么go支持高并发,但是goroutine频繁创建销毁对GC的压力比较大。
220 0
grpool goroutine池详解 | 协程管理