"原子操作(atomic operation)是不需要synchronized",这是多线程编程的老生常谈了。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。
原子操作 通常我们代码中的a = a + 1这样的一行语句,翻译成汇编后蕴含着3条指令: ldr x0, &a add x0,x0,#1 str x0,&a 即 (1)从内存中读取a变量到X0寄存器 (2)X0寄存器加1 (3)将X0写入到内存a中 既然是3条指令,那么就有可能并发,也就意味着返回的结果可能不是预期的。 然后在linux kernel的操作系统中,提供访问原子变量的函数,用来解决上述问题。其中部分原子操作的API如下: atomic_read atomic_add_return(i,v) a
原子操作(atomic operation),不可分割的操作。其通过原子变量来实现,以保证单个CPU周期内,读写该变量,不能被打断,进而判断该变量的值,来解决并发引起的互斥。
综述 在上一篇介绍了linux驱动的调试方法,这一篇介绍一下在驱动编程中会遇到的并发和竟态以及如何处理并发和竞争。 首先什么是并发与竟态呢?并发(concurrency)指的是多个执行单元同时、并行被执行。而并发的执行单元对共享资源(硬件资源和软件上的全局、静态变量)的访问则容易导致竞态(race conditions)。可能导致并发和竟态的情况有: SMP(Symmetric Multi-Processing),对称多处理结构。SMP是一种紧耦合、共享存储的系统模型,它的特点是多个CPU使用共同的系统总线
linux内核中有多种内核锁,内核锁的作用是: 多核处理器下,会存在多个进程处于内核态的情况,而在内核态下,进程是可以访问所有内核数据的,因此要对共享数据进行保护,即互斥处理; linux内核锁机制有信号量、互斥锁、自旋锁还有原子操作。 一、信号量(struct semaphore): 是用来解决进程/线程之间的同步和互斥问题的一种通信机制,是用来保证两个或多个关键代码不被并发调用。 信号量(Saphore)由一个值和一个指针组成,指针指向等待该信号量的进程。信号量的值表示相应资源的使用情况。信号量S>=0
本文补充校正一些Linux内核开发者关于GFP_ATOMIC的认知不完整的地方,阐述GFP_ATOMIC与free内存watermark的关系,并明确什么时候应该用GFP_ATOMIC申请内存。目录:
在多年前,linux还没有支持对称多处理器SMP的时候,避免并发数据访问相对简单。
从reddit/hackernews/lobsters/meetingcpp摘抄一些c++动态
Proper locking can be tough—real tough. Improper locking can result in random crashes and other oddities. Poorly designed locking can result in code that is hard to read, performs poorly and makes your fellow kernel developers cringe. In this article, I explain why kernel code requires locking, provide general rules for proper kernel locking semantics and then outline the various locking primitives in the Linux kernel.
也就是说增长到1000的数组如果没有事先指定大小,会发生13次Arrays.copyOf动作,拷贝代价多大?继续分析
因为现代操作系统是多处理器计算的架构,必然更容易遇到多个进程,多个线程访问共享数据的情况,如下图所示:
注:这篇文章参考了https://www.cnblogs.com/snowater/p/8303698.html,而后自己结合hotspot源码看的
在linux内核中,各个子系统之间有很强的相互关系,某些子系统可能对其他子系统产生的事件比较感兴趣。因此内核引入了notifier机制,当然了notifier机制只能用在内核子系统之间,不能用在内核与应用层之间。比如当系统suspend的时候,就会使用到notifier机制来通知系统的内核线程进行suspend。
Red Hat对Linux 操作系统进行了瘦身,为的是可以创建一种杂糅的技术,来融合VMware,微软和Citrix等支持的传统虚拟方法。
mm_struct 结构体 在 Linux 源码 linux-4.12\include\linux\mm_types.h#359 位置 ;
本文主要讲述如何在自己本地构建起一套小型威胁狩猎平台,同时你也可以基于该小型威胁狩猎平台来辅助你理解ATT&CK相关技术,并了解蓝队视角下红队攻击技术可能会带来哪些痕迹。
原子操作就是在多线程程序中“最小的且不可并行化的”操作,意味着多个线程访问同一个资源时,有且仅有一个线程能对资源进行操作。通常情况下原子操作可以通过互斥的访问方式来保证,例如Linux下的互斥锁(mutex),Windows下的临界区(Critical Section)等。下面看一个Linux环境使用POSIX标准的pthread库实现多线程下的原子操作:
块设备是文件系统的底层支撑,完成数据的存储和访问。块设备也能脱离文件系统以螺设备的形式工作。
如果这个操作序列是串行化的操作(在一个thread中串行执行),那么一切OK,然而,世界总是不能如你所愿。在多CPU体系结构中,运行在两个CPU上的两个内核控制路径同时并行执行上面操作序列,有可能发生下面的场景:
要深入理解Linux内核中的同步与互斥的实现,需要先了解一下内联汇编:在C函数中使用汇编代码。
CAS 的意思是 compare and swap,比较并交换。CAS 的引入是为了解决java锁机制带来的性能问题。锁机制存在以下问题:
并发相关的缺陷是最容易制造的,也是最难找到的,为了响应现代硬件和应用程序的需求,Linux 内核已经发展到同时处理更多事情的时代。这种变革使得内核性能及伸缩性得到了相当大的提高,然而也极大提高了内核编程的复杂性。
i2c_apdater核心是master_xfer函数,它的实现取决于硬件,大概代码如下:
什么是VFS? Linux内核使用工厂的设计模式抽象出实际文件系统统一接口,这个就是虚拟文件系统(VFS),根据应用程序调用虚拟文件系统接口,根据不同的文件系统类型(xfs/zfs/ext4)来调用实
前言:非常早之前就接触过同步这个概念了,可是一直都非常模糊。没有深入地学习了解过,最近有时间了,就花时间研习了一下《linux内核标准教程》和《深入linux设备驱动程序内核机制》这两本书的相关章节。趁刚看完,就把相关的内容总结一下。
我们在阅读一些源代码时经常发现类似这样的宏WIN32,_WIN64,__x86_64,__linux却找不到在哪里定义的,这些其实是编译器预定义的宏。在不同的操作系统内容不同。 为了知道gcc编译器都预定义了哪些宏, 在window下可以输入如下命令:
⑤ 堆内存 : 通过 malloc brk vmalloc 等函数 申请的 动态分配 的内存 ;
funcA先执行,再执行funcB。或者 funcB先执行,再执行funcA。 上述无论那个先执行,结果都是2。没有什么多说的。
来源:Linux阅码场, 罗玉平原创,欢迎投稿原创文章(要求投稿前未在任何平台发表),稿费500元人民币。投稿邮箱:21cnbao@gmail.com
如果你是一个嵌入式开发人员,或者是Linux内核研发人员。可能经常会在内核中遇见如下代码:
linux高端内存中的临时内存区为固定内存区的一部分, 对于固定内存在linux内核中有下面描述
unsafe中对应拥有三个方法 compareAndSwapObject ,compareAndSwapInt和compareAndSwapLong ,他们都被标记为native
汇编指令读写内存变量的过程我们称为read-modify-write,简称为RMW操作。也就是说,它们读写一个内存区域两次,第一次读取旧值,第二次写入新值。
在早期的 Linux内核中,并发的来源相对较少。早期内核不支持对称多处理( symmetric multi processing,SMP),因此,导致并发执行的唯一原因是对硬件中断的服务。这种情况处理起来较为简单,但并不适用于为获得更好的性能而使用更多处理器且强调快速响应事件的系统。
单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。 懒汉模式(Lazy Loading) 懒汉模式是开源项目中使用最多的一种,最大的缺点是非线程安全的 type singleton struct { } // private var instance *singleton // public func GetInstance() *singleton { if
OSTEP中有一段Linux下的互斥锁源代码没有很细研读,今日被tdl,ldl一阵教诲,有所醍醐灌顶。以此笔记。
Linux 内核中的同步机制:原子操作、信号量、读写信号量、自旋锁的API、大内核锁、读写锁、大读者锁、RCU和顺序锁。 1、介绍 在现代操作系统里,同一时间可能有多个内核执行流在执行,即使单CPU内核也需要一些同步机制来同步不同执行单元对共享的数据的访问。 主流的Linux内核中的同步机制包括: 原子操作 信号量(semaphore) 读写信号量(rw_semaphore) 自旋锁spinlock 大内核锁BKL(Big Kernel Lock) 读写锁rwlock、 brlock(只包含在2.4内核中
CAS 全称是 compare and swap,是一种用于在多线程环境下实现同步功能的机制。CAS 操作包含三个操作数 -- 内存位置、预期数值和新值。CAS 的实现逻辑是将内存位置处的数值与预期数值想比较,若相等,则将内存位置处的值替换为新值。若不相等,则不做任何操作。
Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起。(所依据的代码是2.6.32.60) 无论是内核线程还是用户进程,对于内核来说,无非都是task_struct这个数据结构的一个实例而已,task_struct被称为进程描述符(process descriptor),因为它记录了这个进程所有的context。其中有一个被称为'内存描述符‘(memory descriptor)的数据结构mm_struct,抽象并描述了Linux视角下管理进程地址空间的所有信息。 mm_s
使用原子操作典型例子众所周知就是多个线程操作同一个全局变量 i++, 由于对应的汇编指令并不只是一条,在并发访问下可能出现多个线程中的多条指令交错导致部分加操作丢失。全局变量i属于临界资源,当然可以使用加锁的方式保护临界资源,但是加锁开销比较大,用在这里有些杀鸡焉用牛刀。最好的方式是使用内核提供的atomic_t类型的原子变量来进行原子操作。
1.写出最底层Led_Open(),Led_Write(),Led_Read() 2.如何让内核知道下面有我们写好的操作硬件的函数呢?定义一个file_operations结构体(指向Led_Open等底层函数)。使用函数regsiter_chrdev(major,”first_drv”,&first_drv_fops)注册告诉内核(通过major索引)。 3.regsiter_chrdev被谁调用?被驱动入口函数调用。first_drv_init() 4.如何知道调用first_drv_init(),还是其他的函数呢?利用宏module_init(first_drv_init)定义一个结构体,结构体中有函数指针,指向入口函数。 5.出口函数first_drv_exit。卸载驱动unregsiter_chrdev(major,”first_drv”,&first_drv_fops)。如何知道何时来调用first_drv_exit?module_init(first_drv_exit)定义一个结构体,结构体中有函数指针,指向入口函数。
为什么80%的码农都做不了架构师?>>> 默认centos自带的源少了很多好软件,所以需要添加第三方源 一、安装CentOS yum源优先级插件yum-priorities yum insta
~/Downloads/research/linux-5.15.4/include/linux/mm_types.h
Splunk Attack Range是一款针对Splunk安全的模拟测试环境创建工具,该工具完全开源,目前由Splunk威胁研究团队负责维护。
嗨,猫头虎博主在这里!今天,我们来深入探索Go语言的新里程碑——Go 1.19版本的发布。从通用性能的提升到安全性的增强,我们将一探究竟,探索它的新特性和对开发者的影响。如果你对Go语言充满好奇,那就跟随我的脚步,一起深入这个富有魅力的编程世界吧!
一、分布位置上的区别: kmalloc()和__get_free_pages()函数申请的内存位于物理内存的映射区域,而且在物理上也是连续的,它们与真实的物理地址只有一个固定的偏移,因此存在简单的线性关系;(3G+896M)(低端内存); vmalloc函数申请的虚拟内存与物理内存之间也没有简单的换算关系;(高端内存)(3G+896M以上的内存); 二、特性上的区别: 1、kmalloc() void *kmalloc(size_
对于基础类型操作,使用原子变量就可以做到线程安全,那原子操作是如何保证线程安全的呢?linux中的原子变量如下:
"本文从编译、二进制程序文件和运行角度逐级解析了 Linux C 语言程序中几种变量类型"
领取专属 10元无门槛券
手把手带您无忧上云