使用CAS实现无锁列队-链表
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <sys/time.h>
#include <pthread.h> using namespace std; #define MAXLEN 200000 #define NUM_THREADS 8 #define CAS __sync_bool_compare_and_swap
#define FAA __sync_fetch_and_add
#define FAS __sync_fetch_and_sub
#define VCAS __sync_val_compare_and_swap struct node{
int num;
node * next;
node(int i, node* n) :
num(i), next(n)
{}
}; struct list{
node *head;
node *tail;
pthread_mutex_t lock;
int count;
}; void init(list *plist)
{
node *tmp = new node(0, NULL);
plist->head = tmp;
plist->tail = tmp;
plist->count = 0;
pthread_mutex_init(&(plist->lock), NULL);
} int enque_lock(list *plist, int num)
{
node *tmp = new node(num, NULL);
pthread_mutex_lock(&(plist->lock)); plist->tail->next = tmp;
plist->tail = tmp;
plist->count++;
pthread_mutex_unlock(&(plist->lock));
return 0;
}
int enque(list *plist, int num)
{
node *p = NULL;
node *tmp = new node(num, NULL);
do
{
p = plist->tail;
} while (CAS(&(p->next), NULL, tmp) == false);
CAS(&(plist->tail), p, tmp); FAA(&(plist->count), 1);
return 0;
} void deque(list *plist)
{
node *tmp = NULL;
do{
tmp = plist->head;
if (plist->head == plist->tail)
{
printf("err\n");
return;
}
} while (CAS(&(plist->head), tmp, tmp->next) == false);
FAS(&(plist->count), 1);
delete tmp;
return;
} void *SendMsg(void* p)
{
struct timeval tv_begin, tv_end;
gettimeofday(&tv_begin, NULL);
int i = 0;
while (i++ < MAXLEN)
{
enque((list*)p, i);
}
gettimeofday(&tv_end, NULL);
long timeinterval = (tv_end.tv_sec - tv_begin.tv_sec) * 1000000 + (tv_end.tv_usec - tv_begin.tv_usec);
printf("cost %llu us\n", timeinterval);
} void *SendMsg2(void* p)
{
struct timeval tv_begin, tv_end;
gettimeofday(&tv_begin, NULL);
int i = 0;
while (i++ < MAXLEN)
{
enque_lock((list*)p, i);
}
gettimeofday(&tv_end, NULL);
long timeinterval = (tv_end.tv_sec - tv_begin.tv_sec) * 1000000 + (tv_end.tv_usec - tv_begin.tv_usec);
printf("cost %llu us\n", timeinterval);
} int main(void)
{
int rc, i;
pthread_t thread[NUM_THREADS];
list ll;
init(&ll);
for (i = 0; i < NUM_THREADS; i++)
{
printf("Creating thread %i\n", i);
rc = pthread_create(&thread[i], NULL, SendMsg, (void*)&ll);
if (rc)
{
printf("ERROR; return code is %d\n", rc);
return -1;
}
} for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(thread[i], NULL);
} while (ll.count > 0)
{
deque(&ll);
} for (i = 0; i < NUM_THREADS; i++)
{
printf("Creating thread %i\n", i);
rc = pthread_create(&thread[i], NULL, SendMsg2, (void*)&ll);
if (rc)
{
printf("ERROR; return code is %d\n", rc);
return -1;
}
} for (i = 0; i < NUM_THREADS; i++)
{
pthread_join(thread[i], NULL);
}
return 0;
}
测试结果如下:
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
cost 227839 us
cost 228055 us
cost 228034 us
cost 228179 us
cost 228274 us
cost 228328 us
cost 228413 us
cost 228433 us
Creating thread 0
Creating thread 1
Creating thread 2
Creating thread 3
Creating thread 4
Creating thread 5
Creating thread 6
Creating thread 7
cost 486283 us
cost 487499 us
cost 488358 us
cost 488677 us
cost 489118 us
cost 489658 us
cost 489657 us
cost 489735 us
加锁版 耗时 比无锁版耗时多一倍
使用CAS实现无锁列队-链表的更多相关文章
- 使用CAS实现无锁的SkipList
无锁 并发环境下最常用的同步手段是互斥锁和读写锁,例如pthread_mutex和pthread_readwrite_lock,常用的范式为: void ConcurrencyOperation() ...
- CAS实现无锁模式
用多线程实现一个数字的自增长到1000000,分别用无锁模式和锁模式来实现代码. 1.使用ReentrantLock. package test; import java.util.concurren ...
- 基于CAS实现无锁结构
杨乾成 2017310500302 一.题目要求 基于CAS(Compare and Swap)实现一个无锁结构,可考虑queue,stack,hashmap,freelist等. 能够支持多个线程同 ...
- CAS 与 无锁队列
http://coolshell.cn/articles/8239.html http://www.tuicool.com/articles/VZ3IBv http://blog.csdn.net/r ...
- 锁、CAS操作和无锁队列的实现
https://blog.csdn.net/yishizuofei/article/details/78353722 锁的机制 锁和人很像,有的人乐观,总会想到好的一方面,所以只要越努力,就会越幸运: ...
- CAS原子操作实现无锁及性能分析
CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 ...
- DPDK 无锁队列Ring Library原理(学习笔记)
参考自DPDK官方文档原文:http://doc.dpdk.org/guides-20.02/prog_guide/ring_lib.html 针对自己的理解做了一些辅助解释. 1 前置知识 1.1 ...
- 非阻塞同步算法与CAS(Compare and Swap)无锁算法
锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...
- CAS无锁算法与ConcurrentLinkedQueue
CAS:Compare and Swap 比较并交换 java.util.concurrent包完全建立在CAS之上的,没有CAS就没有并发包.并发包借助了CAS无锁算法实现了区别于synchroni ...
随机推荐
- java.lang.IllegalArgumentException: Request header is too large
tomcat运行项目时,有一个请求过去后,后台报这样的错java.lang.IllegalArgumentException: Request header is too large原因:请求头超过了 ...
- open_basedir restriction in effect,解决php引入文件权限问题
一.前言 今天在Ubuntu安装了lnmp环境,运行项目的时候出现了,引入500的错误 二.查看错误 再项目文件入口添加,代码显示错误内容,查看到一下错误 ini_set('display_error ...
- 浅谈服务间通信【MQ在分布式系统中的使用场景】
解决的问题 一项技术的产生必然是为了解决问题而生,了解了一项技术解决的问题,就能够很轻松的理解这项技术的设计根本,从而更好地理解与使用这项技术. 消息中间件和RPC从根本上来说都是为了解决分布式系统的 ...
- 关于<input type="date">这种取值的问题 【原创】
举例 <input type="date" id="date1"> var num = $("#date1").val(); a ...
- Java系列1 -- 浅谈面向对象
也许每一个计算机专业的人,在大学学习java的时候,老师开始时都会说这么一句话,"Java是一门面向对象的语言".那么面向对象到底是什么,他有什么好处,或者他比其他流行的语言C/C ...
- ESXI的安装和部署
1. 实验拓扑图: 2. 实验要求 (1) 新建一台exsi主机,安装exsi5.5系统. 步骤: 1)新建虚拟机,导入光盘. 2)安装esxi系统 (2)在exsi主机中,配置IP地址为1 ...
- Log4j2中RollingFile的文件滚动更新机制
一.什么是RollingFile RollingFileAppender是Log4j2中的一种能够实现日志文件滚动更新(rollover)的Appender. rollover的意思是当满足一定条件( ...
- VMware workstation的基础使用
1. VMware workstation虚拟化平台简介2. VMware workstation提供网络资源3. VMware workstation提供存储资源4. VMware workstat ...
- Javascript保证精度的小数乘法
众所周知,js的小数乘法很容易丢失精度,这是一件很恶心的事情.所以我写了这个方法,保证计算精度./** * js小数乘法 *@parameter arg1:被乘数(接受小数和整数) *@paramet ...
- Java报错信息 java.lang.SecurityException: Prohibited package name: java.xxx
package java.yun.System; public class SystemOut { public static void main(String[] args) { System.ou ...