使用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 ...
随机推荐
- 破解跳过QQ群验证--真实有效哦。
说明:此教程可以实现强行加入别人的群,无需群主或管理员同意.来自于吾爱破解.跟着做了下,应该不用什么技术含量,因为啥也不懂的我也做到了最后.哈哈! 附上软件:https://pan.baidu.com ...
- 集成学习之Boosting —— AdaBoost原理
集成学习大致可分为两大类:Bagging和Boosting.Bagging一般使用强学习器,其个体学习器之间不存在强依赖关系,容易并行.Boosting则使用弱分类器,其个体学习器之间存在强依赖关系, ...
- ASP.NET三剑客 HttpApplication HttpModule HttpHandler 解析
我们都知道,ASP.Net运行时环境中处理请求是通过一系列对象来完成的,包含HttpApplication,HttpModule, HttpHandler.之所以将这三个对象称之为ASP.NET三剑客 ...
- 浏览器中缓存Cache
在请求服务器资源时,服务器会将图片.网页文件等资源保存在客户端的临时文件夹中,称为缓存,当浏览器向服务器请求相同的资源时,如果与服务器版本一致,则从缓存读取 Cookie:服务器存放在 ...
- Android TagFlowLayout完全解析 一款针对Tag的布局
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/48393217: 本文出自:[张鸿洋的博客] 一.概述 本文之前,先提一下关于上 ...
- 查找linux设备的uuid
[root@ ~]# blkid /dev/vdc /dev/vdc: UUID="bxxxx-xxx-41b9-8146-7da8bd645b92" TYPE="ext ...
- 小米笔记本怎么关闭secure boot
关闭Secure Boot的步骤: 一.关闭 "快速启动" 功能 1.右键-开始菜单- 电源选项,进入后 点击"选择电源按钮的功能". 2.进入电源选项设置后, ...
- logger.go
package app //日志接口 type Logger interface { Output(maxdepth int, s string) error }
- 【prufer编码】BZOJ1430 小猴打架
Description 一开始森林里面有N只互不相识的小猴子,它们经常打架,但打架的双方都必须不是好朋友.每次打完架后,打架的双方以及它们的好朋友就会互相认识,成为好朋友.经过N-1次打架之后,整个森 ...
- BZOJ_1954_Pku3764 The xor-longest Path_Trie树
Description 给定一棵n个点的带权树,求树上最长的异或和路径 把根到点路径上点权异或和求出来,然后变成了Trie树裸题. 代码: #include <cstdio> #inc ...