mutex, spinlock, cas

1.多线程数据共享,资源保护方法:
1)mutex
如果获取不到锁,让出CPU,将线程加入等待队列。

任务耗时比上下文切换要长

2)spinlock
如果获取不到锁,则继续死循环检查锁的状态,如果是lock状态,则继续死循环,否则上锁,结束死循环。

(1)任务不能存在阻塞 (2)任务耗时短,几条指令

3)无锁CAS(Compare and Swap)
比较并交换,是一种原子操作

bool CAS( int * pAddr, int nExpected, int nNew )
atomically {
    if ( *pAddr == nExpected ) {
        *pAddr = nNew ;
        return true ;
    } else
    return false ;
}

2.操作的原子性

#include <stdio.h>

int i = 0;
// gcc -S 1_test_i++.c
int main(int argc, char **argv)
{
    ++i;
    return 0;
}

++i 不是原子操作
汇编代码

    movl    i(%rip), %eax //把i从内存加载到寄存器
    addl    $1, %eax //把寄存器的值加1
    movl    %eax, i(%rip) //把寄存器的值写回内存
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;
}

3.原子操作
gcc、g++编译器提供了一组原子操作api

bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)

C++11也提供了一组api,定义在<atomic>中

X86架构原子操作实现

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;
}

4.无锁队列的实现
无锁队列适用于队列push、pop非常频繁的场景,效率要比mutex高很多

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • title: 线程安全问题date: 2019/04/01 17:13 线程安全问题是由于多个线程同时操作同一全局...
    想54256阅读 995评论 0 0
  • 概览进程同步器件的实现方法关系图 原子操作 原子操作:顾名思义就是不可分割的操作,该操作只存在未开始和已完成两种状...
    my_little_world阅读 825评论 0 0
  • Java并发编程 来自Java并发编程的艺术个人博客: http://blog.csdn.net/qq_22329...
    越长越圆阅读 3,342评论 4 54
  • 为什么要有分布式锁 随着架构系统的演进,由纯真的单机架构到容器化编排的分布式架构,可以说是一个大型互联网企业发展的...
    周若谷阅读 525评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,879评论 28 54

友情链接更多精彩内容