使用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 ...
随机推荐
- 使用Eclipse打开已有工程
点击Eclipse界面中的file(文件)下的import(导入). 进入导入界面,选择General下的Exiting Project into Workspace. 点击Select ...
- SSM-SpringMVC-07:SpringMVC中处理器映射器
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- BeanNameUrlHandlerMapping和SimpleUrlHandlerMapping BeanN ...
- linux编译安装时常见错误解决办法
This article is post on https://coderwall.com/p/ggmpfa 原文链接:http://www.bkjia.com/PHPjc/1008013.html ...
- Composer基本安装步骤
Composer是 PHP 世界里用于管理项目依赖的工具. 1,确保安装PHP,检查方法命令行窗口执行php -v,查看是否正常输出版本 php -v 2,下载安装脚本composer-setup.p ...
- pip 安装mysqlclient报错OSError: mysql_config not found
执行 pip install mysqlclient 报错信息如下: [root@CentOS7-demo bin]# pip install mysqlclient Collecting mysql ...
- django(权限、认证)系统——用户Login,Logout
上面两篇文章,讲述的Django的Authentication系统的核心模型对象User API和相关的使用,本文继续深入,讨论如何在Web中使用Authentication系统. 前面说了,Djan ...
- xp开机黑屏故障分析
今天装完xp系统之后,重启开机发现竟然黑屏了,查资料发现有很多用户在修改分辨率后,因显示器不支持修改后的分辨率,会出现电脑黑屏的情况.分辨率调高了,超出了屏幕的范围,肯定会黑屏,而且这个问题还挺麻烦, ...
- wukong.go
package wukong import ( _ "github.com/boltdb/bolt" _ "github.com/cznic/kv&quo ...
- CAD中用户选择实体
在CAD的很多操作中都会有需要用户选择实体的时候,这里将我最近项目中用到的方法分享一下,程序原意是希望用户选择一个单行文本或者多行文本,并返回所选文本的内容,直接上代码: CString CPaint ...
- K短路 (A*算法) [Usaco2008 Mar]牛跑步&[Sdoi2010]魔法猪学院
A*属于搜索的一种,启发式搜索,即:每次搜索时加一个估价函数 这个算法可以用来解决K短路问题,常用的估价函数是:已经走过的距离+期望上最短的距离 通常和Dijkstra一起解决K短路 BZOJ1598 ...