使用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 ...
随机推荐
- html5中让页面缩放的4种方法
1.viewport 这种方法,不是所有的浏览器都兼容<meta name="viewport" content="width=640,minimum-scale= ...
- XamarinForm Effects 调用事件
原文地址 在Xamarin.Forms控件中实现底层多点触控跟踪. 一个effect可以定义和调用一个事件,在底层本地视图中发出信号的变化.这篇文章演示如何实现底层多点触控跟踪,以及如何生成信号触摸活 ...
- Oracle-07:别名,去重,子查询
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 依旧提供数据库脚本供操作 create table DEPT ( deptno ) not null, dna ...
- Java开源生鲜电商平台-监控模块的设计与架构(源码可下载)
Java开源生鲜电商平台-监控模块的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-监控模块的设计与架构,我们谈到监控,一般设计到两个方面的内容: 1. 服务器本身的监控.(比如:linux ...
- UnicodeEncodeError: 'ascii' codec can't encode character...的解决方法
在python2.7下,因为想从数据库中读出来分类名进行写入到文件,提示 Traceback (most recent call last): File "test.py", li ...
- Python爬虫三年没入门,传授一下绝世神功,经理唏嘘不已!
长期枯燥的生活,敲代码的时间三天两头往吸烟室跑,被项目经理抓去训话. "入门"是学习Python最重要的阶段,虽然这个过程也许会非常缓慢.当你心里有一个目标时,那么你学习起来就不会 ...
- Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...
- MYSQL—— Insert的几种用法!
向表中插入数据 标题头示例图如下: 用insert插入值得方式: 1.使用如下语句进行插入值操作,要求:插入值必须与表头给出列数值一致,否则报:[Err] 1136 - Column count do ...
- 《k8s 源码分析》- Custom Controller 之 Informer
Custom Controller 之 Informer 概述 架构概览 reflector - List & Watch API Server Reflector 对象 ListAndWat ...
- C# - 为引用类型重定义相等性
通常情况下引用类型的相等性是不应该被重定义/重写的. 例如两个引用类型的变量 x 和 y,如果这样写:if(x == y) {...},那么大家都明白,这个比较的是引用的相等性. 但是有少数情况下,也 ...