多线程安全CAS实现的无锁
来源:互联网 发布:浅情人不知网络番外 编辑:程序博客网 时间:2024/05/14 17:07
实现无锁队列的关键点有二:
1、各个平台的原子操作或者说CAS原语;
2、ABA问题的理解和解决。
首先来说说这个CAS原语,所谓CAS(Compare And Swap)即比较并交换,在 Intel 处理器中,比较并交换通过指令的 cmpxchg 系列实现。CAS有三个操作数: 内存位置(V)、预期原值(A)和新值(B)。如果内存位置V的值与预期A原值相匹配,那么处理器会自动将该位置值更新为新值B。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。(在 CAS 的一些特殊情况下将仅返回 CAS 是否成功,而不提取当前值。)CAS 有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。”CAS的C语言实现如下:
inline bool CAS2(pointer_t *addr, pointer_t &old_value, pointer_t &new_value)
{
bool ret;
__asm__ __volatile__(
"lock cmpxchg16b %1;\n"
"sete %0;\n"
:"=m"(ret),"+m" (*(volatile pointer_t *) (addr))
:"a" (old_value.ptr), "d" (old_value.tag), "b" (new_value.ptr), "c" (new_value.tag));
return ret;
}
这其中包括了内联汇编代码(这个可以去看看AT&T汇编语法),其中能够支持多线程的并行安全执行的秘诀就在 "lock cmpxchg16b %1;\n"这句中的“lock”,这个lock就和我们基本多线程编程中的锁相当,只不过,这个lock不再是普通的锁,它锁的是地址总线,在多核编程情景下,当已经有CPU的线程A已经访问某地址时,这时地址总线会被锁定,其他CPU核心的线程B无法再访问当前地址,直到A访问完毕之后,其他线程如B才可能访问该地址,这样就保证了线程A访问该地址的原子性操作。
再来讲讲这个ABA问题。在进行CAS操作时,因为在更改V值之前,CAS主要是通过访问V的值是否仍然和A相等,所以,在第一次读取V以及对V执行CAS操作之前,如果有其他线程将V的值先从A改为B,而另外的线程又将V的值从B改回了A,这样会使CAS算法混乱。显然,在这种情况下,CAS的操作会成功,这类的问题称为ABA问题。要解决这类问题,就是不再重用A,通常的做法是用标记或版本编号与进行CAS操作的每个值相关联,并原子的更新值和标记。
CAS实现的无锁
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <time.h> #include "timer.h" int mutex = 0; int lock = 0; int unlock = 1; static volatile int count = 0; void *test_func(void *arg) { int i = 0; for(i = 0; i < 2000000; i++) { while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(100000); count++; __sync_bool_compare_and_swap (&mutex, unlock, 0); } return NULL; } int main(int argc, const char *argv[]) { Timer timer; timer.Start(); pthread_t thread_ids[10]; int i = 0; for(i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); i++) { pthread_create(&thread_ids[i], NULL, test_func, NULL); } for(i = 0; i < sizeof(thread_ids)/sizeof(pthread_t); i++) { pthread_join(thread_ids[i], NULL); } timer.Stop(); timer.Cost_time(); printf("结果:count = %d\n",count); return 0; }
- 多线程安全CAS实现的无锁
- 利用CAS机制实现多进程,多线程下的无锁并发控制
- 多线程安全和高效之无锁机制(CAS)和unsafe类
- 无锁编程(CAS以及java的实现)
- 多线程无锁队列的实现
- 多线程无锁算法之无锁队列的实现
- 多线程无锁算法之无锁队列的实现
- CAS实现多线程计数器
- 多线程安全无锁消息队列
- CAS操作实现并发的优势、以及实现一个无锁队列、怎样解决ABA 问题
- 无锁程序设计(CAS)
- CAS无锁操作
- 一种基于CAS的无锁并发HashTable设计及C代码实现
- Java多线程编程-(14)-无锁CAS操作以及Java中Atomic并发包的“18罗汉”
- Java多线程编程-(16)-无锁CAS操作以及Java中Atomic并发包的“18罗汉”
- ThreadLocal,实现安全的多线程
- 利用CAS操作(Compare & Set)实现无锁队列
- CAS原子操作实现无锁及性能分析
- 在使用Spring的事务注解@Transactional的时候遇到几个坑
- Android 5.0 动画-Ripple和RevealEffect
- pointwise linux ubuntu 安装 纪录
- JDBC
- hdu2037 今年暑假不AC
- 多线程安全CAS实现的无锁
- Unity3D开发基础组件提取总结
- openssl 线程安全 Windows
- 四 、Hive逻辑优化
- myeclipse的buildpath 和lib引入的区别
- UITableView增加搜素框后搜不出来内容(old)
- resteasy框架之PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy
- LeetCode-80-Remove Duplicates from Sorted Array II(递归)-Medium
- IOS自动布局之Autoresizing