CAS无锁队列与线程同步
2021-05-01 16:27
标签:无锁 内存区域 font zmq 汇编代码 volatile atomic 检测 获取 线程同步 同步:同步控制着线程之间的执行顺序,不让他们抢占式执行。在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题,叫做同步。 原子访问:同一时刻,只允许一个线程访问临界资源; 原子操作:指多步操作组成的一个操作;原子操作中线程不会被切换,线程切换要么在原子操作之前,要么在原子操作完成之后。 在单核系统里,单个的机器指令可以看成是原子操作(如果有编译器优化、乱序执行等情况除外);在多核系统中,单个的机器指令就不是原子操作,因为多核系统里是多指令流并行运行的,一个核在执行一个指令时,其他核同时执行的指令有可能操作同一块内存区域,从而出现数据竞争现象。多核系统中的原子操作通常使用内存栅障(memory barrier)来实现,即一个CPU核在执行原子操作时,其他CPU核必须停止对内存操作或者不对指定的内存进行操作,这样才能避免数据竞争问题。 CAS无锁队列: 避免队列放入和读取过于频繁。volatile 修饰变量+type __sync_val_compare_and_swap (type *ptr, type oldval type newval) CAS原理:compare and swap;比较内存有没有被修改,期望值和读出来的值是否一致 应用:无锁队列,ZMQ中的设计用到了cas无锁队列; disruptor库。会涉及到cache的操作的问题:每个CPU都有独立的cache, 当cache修改了,cache1和cache2会失效的问题; 缺点:出了问题很难debug;考验设计能力; mutex互斥锁:如果获取不到锁,线程就会进入休眠,让出CPU资源,线程加入到所等待队列中; 缺点:切换上下文引起的效率的问题;要避免频繁的切换上下文成为应用场景的选择; 临界区执行代码比较长时mutex和spinlock相比较会占优势一点;比如:for(i =0 ;i spinlock自旋锁: 特点:忙等待,继续去检测锁的状态; 应用场景中:1.临界区内不能存在阻塞;2,临界区代码段执行时间不能过长,比如:i++;++i......; ++i;i++; gcc -S Filenale.c Vim Filenam.s 其反汇编代码: movl i(%rip), %eax addl $1, %eax movl %eax, i(%rip) 原子操作指令API:add,sub,or,and,xor,nand X86内存汇编指令加操作:lxx_atomic_add(&s_i, 1); static int lxx_atomic_add(int *ptr, int increment) { int old_value = *ptr; __asm__ volatile("lock; xadd %0, %1 \n\t" : "=r"(old_value), "=m"(*ptr) : "0"(increment), "m"(*ptr) : "cc", "memory"); return *ptr; } CAS无锁队列与线程同步 标签:无锁 内存区域 font zmq 汇编代码 volatile atomic 检测 获取 原文地址:https://www.cnblogs.com/will287248100/p/13205886.html