自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(245)
  • 资源 (3)
  • 收藏
  • 关注

原创 linux内核中的互斥操作

内核中的很多操作在进行的过程中都不容许受到打扰,最典型的例子就是队列操作。如果两个进程都要将一个数据结构链入到同一个队列的尾部,要是在第一个进程完成了一半的时候发生了调度,让第二个进程插了进来,结果很可能就乱了。类似的干扰也有可能来自某个中断服务程序或bh函数。在多处理器SMP结构的系统中,这种感染还有可能来自另个处理器。不过,除了一个进程主动调用schedule染出CPU的情况(显然不会发生在不容许收到干扰的过程中途)之外,只有在系统空间返回到用户空间的前夕才有可能发生调度。这样的安排使得上述两个进程

2021-12-25 15:43:49 1377

原创 linux内核-系统调用nanosleep()与pause()

处于种种原因,运行中的进程常常需要主动进入睡眠状态,并发起一次调度让出CPU。这一定要通过系统调用,或者在系统调用内核才能做到。注意,前面的博客中讲到的系统调用sched_yield与此有所不同,那只是让内核进行一次调度,而当前进程继续保持可运行状态。而这里所说的是,当前进程进入睡眠,也就是将进程的状态变成TASK_INTERRUPTIBLE或TASK_UNINTERRUPTIBLE,并从可执行队列中脱钩,调度的结果一定是其它进程得以运行。并且,进程一旦进入睡眠状态,就需要经过唤醒才能将状态恢复成TASK_

2021-12-19 11:44:18 5325

原创 linux内核-强制性调度

linux内核中进程的强制性调度,也就是非自愿的、被动的、剥夺式的调度,主要是由时间引起的。前面讲过,这种调度发生在进程从系统空间返回用户空间的前夕。当然,并非每次从系统空间返回到用户空间时都会发生此类调度。从前面博客引用entry.S的代码片段ret_with_reschedule可以看出,此时是否真的调用schedule,最终还要取决于当前进程task_struct结构中的need_resched是否为1(非0)。因此,问题就归结为当前进程的need_resched是在什么情况下才置成1的。在目前版本的

2021-12-19 11:21:53 1137

原创 linux内核-进程的调度与切换

在多进程的操作系统中,进程调度是一个全局性的、关键性的问题,它对系统的总体设计、系统的实现、功能设置以及各个方面的性能都有着决定性的影响。根据调度结果所做的进程切换的速度,也是衡量一个操作系统性能的重要指标。进程调度机制的设计,还对系统复杂性有着极大的影响,常常会由于实现的复杂程度而在功能与性能方面做出必要的权衡和让步。一个好的系统的进程调度机制,要兼顾三种不同应用的需要:...

2021-12-12 22:45:44 1860

原创 linux内核-系统调用exit与wait4

系统调用exit与wait4的代码基本上都在kernel/exit.c中,下面我们在引用代码时凡不特别说明出处的均来自这个文件。先来看exit的实现(kernel/exit.c):asmlinkage long sys_exit(int error_code){ do_exit((error_code&0xff)<<8);}显然,其主体为do_exit。先看它的前半部:NORET_TYPE void do_exit(long code){ struct t

2021-12-05 15:37:22 1513

原创 sslsniff编译错误

st::asio::ip::tcp::socket&, boost::asio::ip::tcp::endpoint&)’:util/Destination.cpp:49:25: error: ‘boost::asio::ip::tcp::socket’ {aka ‘class boost::asio::basic_stream_socket<boost::asio::ip::tcp>’} has no member named ‘native’参考boost::asi.

2021-11-30 14:24:55 2757

原创 linux内核-系统调用execve()

​读者在linux内核-系统调用fork、vfork与clone中已经看到,进程通常是按其父进程的原样复制出来的,在多数情况下,如果复制出来的子进程不能与父进程分道扬镳,走自己的路,那就没多大意义。所以,执行一个新的可执行程序时进程生命历程中关键性的一步。linux为此提供了一个系统调用execve,而在C语言的程序库中则又在此基础上向应用程序提供一整套的库函数,包括execl、execlp、execle、execlco、execve和execvp。此外,还有库函数system,也与execve有...

2021-11-28 22:01:27 4088 2

原创 linux内核-系统调用fork、vfork与clone

前面已经简要地介绍过fork与clone二者的作用于区别。这里先来看一下二者在程序设计接口上的不同:pid_t fork(void);int clone(int (*fn)(void *), void *stack, int flags, void *arg, ... /* pid_t *parent_tid, void *tls, pid_t *child_tid */ );系统调用clone的主要作用是创建一个线程,这个线程可以是内核线程,也可以是用户线程。

2021-11-21 16:39:45 2227

原创 linux内核-进程三部曲:创建、执行与消亡

就像世上万物都有产生、发展与消亡的过程一样,每个进程也有被创建、执行某段程序以后最后消亡的过程。在linux系统中,第一个进程时系统固有的、与生俱来的或者说是由内核的设计者安排好了的。内核在引导并完成了基本的初始化以后,就有了系统的第一个进程(实际上是内核线程)。除此之外,所有其他的进程和内核线程都由这个原始进程或其子孙进程所创建,都是这个原始进程的后代。在linux系统中,一个新的进程一定要由一个已经存在的进程复制出来,而不是创造出来(而所谓创建实际就是复制)。所以,linux系统(Unix也一样)并不向

2021-11-21 09:29:27 903

原创 linux-2.6.11.12内核中的epoll数据结构和机制简析

大家都知道epoll的效率比poll和select性能高很多,原因在于在实现时,内核为epoll设置了一个文件系统,并且使用的是红黑树来增删改查struct epitem,然后在监控的文件描述符有数据时,通过回调将struct epitem挂载到struct eventpoll的就绪队列中,不需要将整个fd集合发送到用户态,并轮询查找就绪fd,效率高。

2021-11-14 19:46:47 1232

原创 linux内核-进程与进程调度

进程四要素要给进程下一个确切的定义不是件容易的事情。不过,一般来说linux系统中的进程都具备下列诸要素:有一段程序供其执行,就好像一场戏要有个剧本一样。这段程序不一定是进程所专有,可以与其他进程共用,就好像不同剧团的许多场演出可以共用一个剧本一样。 有起码的私有财产,这就是进程专用的系统堆栈空间。 有户口,这就是在内核中的一个task_struct数据结构,操作系统教科书中常称为进程控制块。有了这个数据结构,进程才能成为内核调度的一个基本单位接受内核的调度。同时,这个结构又是进程的财产登记卡,

2021-11-07 20:09:41 498

原创 linux内核-系统调用号与跳转表

文件include/asm-i386/unistd.h为每个系统调用定义了一个唯一的编号,称为系统调用号。部分编号如下所示:#define __NR_exit 1#define __NR_fork 2#define __NR_read 3#define __NR_write 4#define __NR_open 5#define __NR_close 6#define __NR_waitpid 7#define __NR_creat 8#

2021-11-07 19:18:23 1382

原创 linux内核-系统调用

如果说外部中断是使CPU被动地、异步地进入系统空间的一种手段,那么系统调用就是CPU主动地、同步地进入系统空间的手段。这里所谓主动,是指CPU自愿的、事先计划好了的行为。而同步则是说,CPU(实际上是软件的设计人员)确切地知道在执行哪一条指令以后就一定会进入系统空间。相比之下,中断的发生带有很大的不可预测性。但是,尽管有着这样的区别,二者之间还是由很大的共性。这是因为,在使CPU的运行状态从用户态转入系统态,也就是从用户空间进入系统空间,这一个基本点上二者是一致的。当然,中断有可能发生在CPU已经运行在系统

2021-11-07 09:22:22 840

原创 linux内核-时钟中断

在所有的外部中断中,时钟中断起着特殊的作用,其作用远非单纯的计时所能相比。当然,即使是单纯的计时也已经足够重要了。别的不说,没有正确的时间关系,你用来重建内核的工具make就不能正常运行了,因为make是靠时间标记来确定是否需要重新编译以及链接的。瞌睡时钟中断的重要性还远不止于此。我们在中断的博客中看到,内核在每次中断(以及系统调用和异常)服务完毕返回用户空间之前都要检查是否需要调度,若有需要就进行进程调度。事实上,调度只有当CPU在内核中运行时才能发生。在进程的博客中,读者将会看到进程调度发生在两种情

2021-11-06 21:41:34 2648

原创 linux内核-页面异常的进入返回

我们在内存管理中介绍内对页面异常处理时,是从do_page_fault开始的。当时因为尚未介绍CPU的中断和异常机制,所以暂时跳过了对页面异常的响应过程,也就是从发生异常至CPU到达do_page_fault之间的那一段路程,以及do_page_fault返回之后到CPU返回到用户空间这一段路程。我们可以来补上这个缺口了。与外设中断不同,各种异常都有为其保留的专用中断向量,因此相应的初始化也是直截了当的,这一点我们已经在初始化的博客中看到了。为页面异常设置的中断门指向程序入口page_fault(见

2021-11-06 16:02:40 326

原创 linux内核-软中断与Bottom Half

中断服务一般都是在将中断请求关闭的条件下执行的,以避免嵌套而使控制复杂化。可是,如果关中断的时间持续太长就可能因为CPU不能及时响应其他的中断请求而使中断(请求)丢失,为此,内核允许在将具体的中断服务程序挂入中断请求队列时将SA_INTERRUPT标志置成0,使这个中断服务程序在开中断的条件下执行。然而,实际的情况往往是:若是服务的全过程关中断则扩大打击面,而全称开中断则又造成不安定因素,很难取舍。一般来说,一次中盾服务的过程常常可以分成两部分。开头的部分往往是必须在关中断条件下执行的。这样才能在不受干扰的

2021-11-03 23:23:40 622

原创 linux内核-中断的响应和服务

搞清了i386 CPU的中断机制和内核中有关的初始化以后,我们就可以从中断请求的发生到CPU的响应,再到中断服务程序的调用与返回,沿着CPU所经历的路线走一遍。这样,既可以弄清和理解linux内核对中断响应和服务的总体的格局和安排,还可以顺着这个过程介绍内核中的一些相关的基础设施。对此二者的了解和理解,有助于读者对整个内核的理解。这里,我们假定外设的驱动程序都已经完成了初始化,并且把相应的中断服务程序挂入到特定的中断请求队列中,系统正在用户空间正常运行(所以中断必然是开着的),并且某个外设已经产生了一次

2021-10-31 16:46:44 909

原创 linux内核-中断请求队列的初始化

在前一篇博客中,我们讲到中断向量表(更确切地,应该说中段描述表)IDT有两种表项,一种是为保留专用于CPU本身的中断门,主要用于由CPU产生到的异常,如除数为0、页面错等等,以后由用户程序通过INT指令产生的中断(或称陷阱),主要用来产生系统调用(另外还有个用于debug的INT 3)。这些中断门的向量除用于系统调用的0x80外都在0x20以下。从0x20开始就是第二种表项,共224项,都是用于外设的通用中断门。这二者的区别在于通用中断门可以为多个中断源所共享,而专用中断门则是为特定的中断源所专用。由于

2021-10-31 12:56:31 319

原创 linux内核-中断向量表IDT的初始化

linux内核在初始化阶段完成了对页式虚存管理的初始化以后,便调用trap_init和init_IRQ两个函数进行中断机制的初始化。其中trap_init主要是对一些系统保留的中断向量的初始化,而init_IRQ则主要用于外设的中断。函数trap_init是在include/i386/kernel/traps.c中定义的:void __init trap_init(void){#ifdef CONFIG_EISA if (isa_readl(0x0FFFD9) == 'E'+('I'<

2021-10-30 22:56:56 1184

原创 i386的页式内存管理机制

学过操作系统原理的读者都知道,内存管理有两种,一种是段式管理,另一种是页式管理,而页式管理更为先进。从80年代中期开始,页式内存管理进入了各种操作系统(以Unix为主)的内核,一时成为操作系统领域的一个热点。Intel从80286开始实现其保护模式,也即段式内存管理。但是很快发现,光有段式内存管理而没有也是内存管理是不够的,那样会使它的x86系列逐渐失去竞争力以及作为主流CPU产品的地位。因此,在不久以后的80386中就实现了对页式内存管理的支持。也就是说,80386除了完成并完善从80286开始的段式

2021-10-30 16:28:39 195

原创 Intel x86 CPU系列的寻址方式

Intel可以说是资格最老的微处理器芯片制造商了,历史上的第一个微处理器芯片4004就会Intel制造的。所谓x86系列,是指Intel从16位微处理器8086开始的整个CPU芯片系列,系列汇总的每种型号都保持与前面的各种型号兼容,主要有8086、8088、80186、80286、80386、80486以及各种型号的Pentium芯片。自从IBM选择8088用于PC个人计算机以后,x86系列的发证就与IBM PC及其兼容机的发展休戚相关了。其中80186并不广为人知,就与IBM当初决定停止在PC机中使用80

2021-10-30 16:02:16 955

原创 linux内核源代码中的汇编语言代码

任何一个用高级语言编写的操作系统,其内核源代码中总有少部分代码是用汇编语言编写的。读过Unix SysV源代码的读者都知道,在其约3万行的核心代码中用汇编语言编写的代码约2000行,分成不到20个扩展名为.s和.m的文件,其中大部分是关于中断与异常处理的底层程序,还有就是与初始化有关的程序以及一些核心代码中调用的公用子程序。用汇编语言辨析核心代码中的部分代码,大体上是出于如下几个方面的考虑:操作系统内核中的底层程序直接与硬件打交道,需要用到一些专用指令,而这些指令在C语言中并无对应的语言成分。例如,

2021-10-29 22:45:30 842

原创 linux内核-X86CPU对中断的硬件支持

本博客不讨论严格意义上的中断响应全过程(比如说,怎样获得中断向量),而是着重讨论CPU在响应中断时,即在得到了中断向量以后,怎样进入相应的中断服务程序的过程。这是从操作系统的角度需要关心的问题。Intel x86 CPU支持256个不同的中断向量,这一点至今未变。可是,早期x86 CPU的中断响应机制非常原始、非常简单的。在实地址模式中,CPU把内存中从0开始的1K字节作为一个中断向量表。表中的每一个表项占四个字节,由两个字节的段地址和两个字节的位移组成。这样构成的地址便是相应中断服务程序的入口地址。这与1

2021-10-24 20:09:13 2404

原创 linux内核-中断、异常和系统调用

我们假定博客的读者已经具备了计算机系统结构方面的基础知识,所以本系列博客对中断以及异常(exception)处理的原理和机制不作深入的介绍。缺乏这方面基础的读者不妨先阅读一些微处理器方面的材料。不过,我们也并不要求读者对相关内容已经具备了很深入的理解。事实上,随着我们的介绍和分析,特别是随着各个情景的发展和代码的阅读,读者自会逐步地加深理解。先简要提一下,中断有两种,一种是由CPU外部产生的,另一种是由CPU本身在执行程序的过程中产生的。外部中断,就是通常所讲的中断(interrupt)。对于执行中

2021-10-24 17:24:36 145

原创 linux内存管理-系统调用mmap()

一个进程可以通过系统调用mmap,将一个已打开文件的内容映射到它的用户空间,其用户界面为:void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);参数fd代表着一个已打开文件,offset为文件中的起点,而addr为映射到用户空间中的起始地址,length则为长度。还有两个参数prot和flags,前者用于对映射区间的访问模式,如可写、可执行等等,后者则用于

2021-10-24 10:21:33 2707

原创 linux内存管理-系统调用brk()

尽管可见度不高,brk也许是最常使用的系统调用了,用户进程通过它向内核申请空间。人们常常并不意识到在调用brk,原因在于很少有人会直接使用系统调用brk向系统申请空间,而总是通过像malloc一类的C语言库函数(或语言成分,如C++中的new)间接地调用brk。如果把malloc想象成零售,brk则是批发。库函数malloc为用户进程(malloc本身就是该进程的一部分)维持一个小仓库,当进程需要使用更多的内存空间时就向小仓库要,小仓库中存量不足时就通过brk向内核批发。前面讲过,每个进程拥有3GB字节

2021-10-23 19:30:21 6096 2

原创 linux内存管理-外部设备存储空间的地址映射

任何系统都免不了要由输入、输出,所以对外部设备的访问是CPU设计中的一个重要问题。一般来说,对外部设备的访问有两种不同的形式,一种叫做内存映射式(memory mapped),另一种叫IO映射式(I/O mapped)。在采用内存映射方式的CPU中,外部设备的存储单元,如控制寄存器、状态寄存器、数据寄存器等等,是作为内存的一部分出现在系统中的。CPU可以向访问一个内存单元一样的访问外部设备的存储单元,所以不需要专门设立用于外设I/O的指令。从前的PDP-11、后来的M68K、PowerPC等CPU都采用这种

2021-10-23 16:18:38 1090

原创 linux内存管理-内核缓冲区的管理

可想而知,内核在运行中常常会需要使用一些缓冲区。例如,当要建立一个新的进程时就要增加一个task_struct结构,而当进程撤销时就要释放本进程的task结构。这些小块存储空间的使用并不局限于某一个子程序,否则就可以作为整个子程序的局部变量而使用堆栈空间了。另外,这些小块存储空间又是动态变化的,不像用于内存管理的page结构那样,有多大的内存就有多少个page结构,构成一个静态的阵列。由于事先根本无法预测运行中各种不同数据结构对缓冲区的需求,不适合为每一种可能用到的数据结构建立一个缓冲池,因为那样的话很可能

2021-10-22 21:40:03 925

原创 linux内存管理-页面的换入

在i386 CPU将一个线性地址映射成物理地址的过程中,如果该地址的映射已经建立,但是发现相应页面表项或目录项中的P(present)标志位为0,则表明相应的物理页面不在内存中,从而无法完成本次内存访问。从理论上说,也许应该把这种情况称为受阻而不是失败,因为映射的关系毕竟已经建立,理应与尚未建立映射的情况有所区别,所以我们称为断开。但是,CPU的MMU硬件并不区分这两种不同的情况,只要P标志位为0就都认为是页面映射失败,CPU就会产生一次页面异常(page fault)。事实上,CPU在映射过程中首先看的就

2021-10-18 23:18:35 492

原创 linux内存管理-页面的定期换出

这个情景比较长,我们得有点耐心。为了避免总是在CPU忙碌的时候,也就是在缺页异常发生的时候,临时再来搜索可供换出的内存页面并加以换出,linux内核定期地检查并预先将若干页面换出,腾出空间,以减轻系统在缺页异常发生时的负担。当然,由于无法确定地预测页面的使用,即使这样做了也还是不能完全杜绝在缺页异常发生时内存内有空闲页面,而只好临时寻找可换出页面的可能。但是,这样毕竟可以减少其发生的概率。并且,通过选择适当的参数,例如每隔多久换出一次,每次换出多少页面,可以使得在缺页异常发生时必须临时寻找页面换出的情况

2021-10-12 23:18:45 520

原创 linux内存管理-物理页面的分配

前面的博客中曾经提到,当需要分配若干内存页面时,用于DMA的内存页面必须是连续的。其实,为便于管理,特别是处于对物理存储空间质地一致性的考虑,即使不是用于DMA的内存页面也是连续分配的。当一个进程需要分配若干连续的物理页面时,可以通过alloc_pages来完成。linux2.4.0内核版本的代码中有两个alloc_pages,一个是在mm/numa.c中,另一个在mm/page_alloc.c中,编译时根据所定义的条件编译选择CONFIG_DISCONTIGMEM决定取舍。为什么呢?这就是出于前面博客

2021-10-10 16:25:36 480

原创 linux内存管理-物理页面的使用与周转

除CPU之外,对于像linux这样的现代操作系统来说,物理存储页面可以说是最基本、最重要的资源了。物理存储页面在系统中的使用和周转就好像资金在企业中的使用和周转一样重要。因此,我们对此最后能有更多一些的了解。首先要澄清本系列博客中使用的几个术语。“虚存页面”,是指在虚拟地址空间中一个固定大小,边界与页面大小(4KB)对齐的区间及其内容。虚存页面最终要落实到,或者说要映射到某汇总物理存储介质上,那就是物理页面。根据具体介质的不同,一个物理页面可以再内存中,也可以在磁盘上。为了区分这两种情况,本博客将分别称

2021-10-10 11:37:21 430

原创 linux内存管理-用户堆栈的扩展

在上一情景中,我们游览参观了一次因越界访问而造成映射失败从而引起进程流产的过程。但是,我们也许会感到惊奇,越界访问有时是正常的。不过,这只是发生在一种情况下,现在我们就来看看当用户堆栈过小,但是因越界访问而因祸得福得以伸展的情景。在阅读本情景之前,我们应该温习一下前一个情景。假设在进程运行的过程中,已经用尽了为本进程分配的堆栈区间,也就是从堆栈的顶部开始(记住,堆栈是从上向下伸展的),已经到达了已经映射的堆栈区间的下沿。或者说,CPU中的堆栈指针%esp已经指向堆栈区间的起始地址。见下图:假

2021-10-07 17:46:05 659

原创 linux内存管理-越界访问

页式存储管理机制通过页面目录和页面表将每个线性地址(也可以称为虚拟地址)转换成物理地址。如果在这个过程中遇到某种阻碍而使CPU无法最终访问到相应的物理内存单元,映射就失败了。而当前的指令也就不能执行完成。此时CPU会产生一次页面出错(page fault)异常(也称缺页异常中断),进而执行预定的页面异常处理程序,使应用程序得以因映射失败而暂停的指令处开始恢复执行,或进行一些善后处理。这里所说的阻碍可以由以下几种情况:相应的页面目录项或页面表项为空,也就是该线性地址与物理地址的映射关系尚未建立,或者已经撤

2021-10-05 17:06:30 1058

原创 linux内存管理-几个重要的数据结构和函数

从硬件的角度来说,linux内核只要能为硬件准备好页面目录PGD、页面表PT以及全局段描述表GDT和局部段描述表LDT,并正确地甚至设置有关的寄存器,就完成了内存管理机制中地址映射部分的准备工作。虽然最终的目的是地址映射,但是实际上内核所需要做的管理工作却要复杂的多。在于内存管理有关的内核代码中,有几个数据结构是很重要的,这些数据结构及其使用构成了代码中内存管理的基本框架。页面目录PGD、中建目录PMD和页面表PT分别是由表项pgd_t、pmd_t记忆pte_t构成的数组,而这些表项又都是数据结构,定义如

2021-10-04 20:59:10 861

原创 linux内存管理-地址映射的全过程

linux内核采用页式存储管理。虚拟地址空间划分成固定大小的页面,由MMU在运行时将虚拟地址映射成(或者说变换成)某个物理内存页面中地址。与段式存储管理相比,页式存储管理有很多好处。首先,页面都是固定大小的,便于管理。更重要的是,当要将一部分屋里空间的内容换出到磁盘上的时候,在段式存储管理中要将整个段(通常都很大)都换出,而在页式存储管理中则是按页进行,效率显然要高得多。页式存储管理与段式存储罐所要求的硬件支持不同,一种CPU既然支持页式存储管理,就无需再支持段式存储管理。但是,i386的情况比较特殊,不管

2021-10-04 12:15:26 1870

原创 linux内存管理的基本框架

i386 CPU中的页式存储管理的基本思路是:通过页面目录和页面表分两个层次实现从线性地址到物理地址的映射。这种映射模式在大多数情况下可以节省页面表所占用的空间。因为大多是进程不会用到整个虚存空间,在虚存空间中通常都留有很大的空洞。采用两层的方式,只要一个目录项所对应的那部分空间是个空洞,就可以把该目录项设置成空,从而省下了与之对应的页面表(1024个页面描述项)。当地址的宽度为32位时,两层映射机制比较有效也比较合理。但是,当地址的宽度大于32位时,两层映射显得不尽合理,不够有效了。

2021-10-03 22:20:40 262

原创 linux文件系统-访问权限与文件安全性

Unix操作系统从一开始就在其文件系统中引入了文件、访问权限等概念,并在此基础上实现了有利于提高文件安全性的机制。从那以后这些概念和机制就一直被继承下来并进一步得到改进和完善。即使在经过了很多年后的今天,而且在计算机系统的安全性已经成为一个突出问题的情况下,这一套机制仍然不失其先进性。尽管还存在一些缺点和需要进一步改进的地方,从总体上说还是瑕不掩瑜。与当今正在广泛使用的其他操作系统相比,可以说Unix的安全性总的来说至少不会差于这些系统;如果考虑到近年来在Unix及linux中已经作出的改进以及不难作出的进

2021-10-02 20:45:57 1981

原创 linux文件系统-特殊文件系统/proc

早期的Unix在设备文件目录/dev下设置了一个特殊文件,称为/dev/mem。通过这个文件可以读写系统的整个物理内存,而物理内存的地址就用读写文件内部的位移量。这个特殊文件同样适用于read、write、lseek等常规的文件操作,从而提供了一个在内核外部动态地读写包括内核映像和内核中各个数据结构以及堆栈内容的手段。这个手段既可以用于收集状态信息和统计信息,也可以用于程序调试,还可以动态地给内核打补丁或者改变一些数据结构或变量的内容。采用虚存以后,Unix又增加了一个特殊文件/dev/kmem,对应于系统

2021-09-26 20:27:08 862 1

原创 linux文件系统-其他文件操作

系统调用open、close、write、read无疑是最基本、最重要、而且也是最复杂的文件操作。除此以外,还有许多用于文件操作或与文件操作有关的系统调用。尽管这些系统调用相比之下只是辅助性的,但是在不同的应用中分别起着很重要的作用,限于篇幅,我们不可能对所有这些系统调用都一一列举并加以介绍。我们可以在后面讲解的系统调用函数跳转表中找到与所有这些系统调用对应的内核函数,对于这些(未必是全部)系统调用的作用于运用可以参考关于Unix、linux程序设计的专著。至于实现这些系统调用的代码,则大多数后面自己要下工

2021-09-25 14:28:57 511

userspace-rcu.rar

liburcu是一个LGPLv2.1用户空间RCU(读取 - 复制 - 更新)库。 此数据同步库提供读取端访问,该访问可随CPU核数量线性扩展。 liburcu-cds提供基于RCU和无锁算法的高效数据结构。 这些结构包括哈希表,队列,堆栈和双向链表。

2019-08-08

tokyo cabinet 源码

2017-01-20

可行性研究与需求分析

可行性研究与需求分析 需求分析掌握软件需求分析的任务与目标及Warnier图的使用,熟悉需求规格说明书的基本结构

2011-09-15

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除