锁和原子操作CAS的底层实现

简介: 锁和原子操作CAS的底层实现

案例:

       买火车票时,有个座位号,第几排第几个座,一排五个座位,买一个座位少一个座位,通过count++%5觉得了买的票在第几个座位,count++/5决定了在第几排;假设开十个线程;

       通过如下代码创建线程:    

在linux内核中没有进程线程之分,统一叫做task_struct,当调用pthread_create函数时,创建task_struct,创建这个结构体后的状态是new,就绪,等待,执行,退出都是线程的状态;new这个状态是还没有运行的,将其加入到队列中,这个new状态和就绪状态是一样的状态;什么时候调度是由调度器本身所决定的,不是由我们所决定的;pthread_create函数执行后什么时候运行创建的线程是不确定的,线程创建后就加入到了就绪队列中等待着被执行;  当调度器发现创建的func线程没有被执行过的时候,这个线程从new状态开始被回调,并传入count参数;调用pthread_join等待对应线程执行完返回pthread_join再往下执行,pthread_join函数是条件等待;

当有多个线程时对count++时对应的汇编代码,会出现线程1的汇编代码没有执行完,线程2就接着执行的情况;

如何解决上述问题呢?

1、互斥锁ptread_mutex_t,可以干其他事情,获得锁再执行;

2、自旋锁pthread_spinlock_t,不会干其他事情,死等直到获得锁再执行;

3、原子操作 ,即能用一条指令执行不可分割;将count++分割成汇编代码封装到inc函数中,成为不可分割的整体,如下汇编代码;

互斥锁和自旋锁和原子操作在这种场景下哪种更好;原子操作最快,所用时间最短;

下图CAS即比较后赋值,单例模式中使用这种方式实现原子操作’

原子操作的经典几个如add,sub,inc,dec,cas;

4、cpu亲缘性

       如何更加高效的利用cpu,比如有4核cpu,我们应该创建多少个线程;我们可以创建4个线程分别绑定到绑定到每个cpu上面;操作系统提供了固定的做法;

       通过cpu_set_t做粘合,比如4个cpu,进程或线程需要绑定哪个cpu,就将cpu_set_t对应位设置为1;绑定后进程或线程就只在对应cpu上运行;

上面代码中,cpu_set_t设置cpu组,这里时4个cpu,然后通过CPU_ZERO把mask清空,然后对进程self_id取模并使用这个值对mask对应位置1;然后通过sched_setaffinity对进程和cpu做粘合;粘合和进程就会只在对应cpu上运行;两个进程可以绑定在一个cpu上面;当一个进程有多个线程时,绑定的是主线程,子线程得通过子线程id去绑定cpu;

5、shmem,共享内存的做法;

       一个大文件,如何快速的读到内存中;把文件通过mmap映射到内存中,然后开启多个线程去读数据;

       mmap为什么快?磁盘的数据读到内存中通常通过cpu参与一一执行;而mmap映射是通过dma的方式,当我们一开始数据就已经到内存中了;dma是磁盘和内存间数据传输的一种方式,cpu不用参与;我们所说的零拷贝,是cpu不参与;mmap是实现共享内存的一种方式;

       可通过shm一系列接口实现映射内存;对应nginx代码如下

目录
相关文章
|
7月前
|
算法 程序员 C语言
C/C++原子操作与atomic CAS底层实现原理
假定有两个操作A 和B,如果从执行A 的线程来看,当另一个线程执行B 时,要么将B 全部执行完,要么完全不执行B,那么A 和B 对彼此来说是原子的。
563 1
C/C++原子操作与atomic CAS底层实现原理
|
存储 编译器 API
锁与原子操作CAS
锁与原子操作CAS
154 0
|
3月前
|
安全 Java 编译器
线程安全问题和锁
本文详细介绍了线程的状态及其转换,包括新建、就绪、等待、超时等待、阻塞和终止状态,并通过示例说明了各状态的特点。接着,文章深入探讨了线程安全问题,分析了多线程环境下变量修改引发的数据异常,并通过使用 `synchronized` 关键字和 `volatile` 解决内存可见性问题。最后,文章讲解了锁的概念,包括同步代码块、同步方法以及 `Lock` 接口,并讨论了死锁现象及其产生的原因与解决方案。
92 10
线程安全问题和锁
|
4月前
|
Java
什么是 CAS(自旋锁)? 它的优缺点? 如何使用CAS实现一把锁?
该博客文章解释了什么是CAS(自旋锁),包括CAS的基本概念、实现原理、优缺点,以及如何使用CAS实现锁的逻辑,并提供了使用CAS实现锁的Java完整代码示例和测试结果。
什么是 CAS(自旋锁)? 它的优缺点? 如何使用CAS实现一把锁?
|
6月前
|
安全 程序员 C++
C++一分钟之-原子操作与线程安全
【6月更文挑战第27天】**C++的`std::atomic`提供线程安全的原子操作,解决多线程数据竞争。涵盖原子操作概念、应用、问题与对策。例如,用于计数器、标志位,但选择数据类型、内存顺序及操作组合需谨慎。正确使用能避免锁,提升并发性能。代码示例展示自旋锁和线程安全计数。了解并恰当运用原子操作至关重要。**
104 1
|
API 调度 C语言
互斥锁,自旋锁,原子操作的原理,区别和实现
v互斥锁,自旋锁,原子操作的原理,区别和实现
145 0
|
7月前
|
算法 调度 数据安全/隐私保护
什么是CAS锁
什么是CAS锁
93 0
|
7月前
|
算法
原子操作CAS
原子操作CAS
45 0
|
7月前
|
存储 安全 中间件
锁与原子操作CAS的底层实现
锁与原子操作CAS的底层实现
|
7月前
|
缓存 Linux API
原子操作CAS与锁实现
原子操作CAS与锁实现
下一篇
DataWorks