系统调用

笔记基本分类-用户态_内核态

我的梦境 提交于 2020-02-07 15:49:52
内核态(Kernel Mode)与用户态(User Mode) 原文: http://www.cnblogs.com/zemliu/p/3695503.html 内核态: CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序 用户态: 只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取 为什么要有用户态和内核态 由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 -- 用户态 和 内核态 用户态与内核态的切换 所有用户程序都是运行在用户态的, 但是有时候程序确实需要做一些内核态的事情, 例如从硬盘读取数据, 或者从键盘获取输入等. 而唯一可以做这些事情的就是操作系统, 所以此时程序就需要先操作系统请求以程序的名义来执行这些操作. 这时需要一个这样的机制: 用户态程序切换到内核态, 但是不能控制在内核态中执行的指令 这种机制叫系统调用, 在CPU中的实现称之为陷阱指令(Trap Instruction) 他们的工作流程如下: 1. 用户态程序将一些数据值放在寄存器中, 或者使用参数创建一个堆栈(stack frame), 以此表明需要操作系统提供的服务. 2. 用户态程序执行陷阱指令 3.

linux内核分析笔记----系统调用

自古美人都是妖i 提交于 2020-02-07 15:39:57
在Linux中,系统调用是用户空间访问内核的唯一手段,它们是内核唯一的合法入口。实际上,其他的像设备文件和/proc之类的方式,最终也还是要通过系统调用进 行的。 一般情况下,应用程序通过应用编程接口(API)而不是直接通过系统调用来编程,而且这种编程接口实际上并不需要和内核提供的系统调用对应。一个API定义了一组 应用程序使用的编程接口。它们可以实现成一个系统调用,也可以通过调用多个系统调用来实现,即使不使用任何系统调用也不存在问题。实际上,API可以在各种不同 的操作系统上实现,给应用程序提供完全相同的接口,而它们本身在这些系统上的实现却可能迥异。 在Unix世界中,最流行的应用编程接口是基于POSIX标准的,Linux是与POSIX兼容的。 从程序员的角度看,他们只需要给API打交道就可以了,而内核只跟系统调用打交道;库函数及应用程序是怎么使用系统调用不是内核关心的。 系统调用(在linux中常称作syscalls)通常通过函数进行调用。它们通常都需要定义一个或几个参数(输入)而且可能产生一些副作用。这些副作用通过一个long类型的返 回值来表示成功(0值)或者错误(负值)。在系统调用出现错误的时候会把错误码写入errno全局变量。通过调用perror()函数,可以把该变量翻译成用户可以理解的错误字 符串。 系统调用的实现有两个特别之处:1

用户态与内核态的切换

ぃ、小莉子 提交于 2020-02-07 13:54:23
内核态与用户态的理解: 2)特权级 熟悉Unix/Linux系统的人都知道,fork的工作实际上是以系统调用的方式完成相应功能的,具体的工作是由sys_fork负责实施。其实无论是不是Unix或者Linux,对于任何操作系统来说,创建一个新的进程都是属于核心功能,因为它要做很多底层细致地工作,消耗系统的物理资源,比如分配物理内存,从父进程拷贝相关信息,拷贝设置页目录页表等等,这些显然不能随便让哪个程序就能去做,于是就自然引出特权级别的概念,显然,最关键性的权力必须由高特权级的程序来执行,这样才可以做到集中管理,减少有限资源的访问和使用冲突。 特权级显然是非常有效的管理和控制程序执行的手段,因此在硬件上对特权级做了很多支持,就Intel x86架构的CPU来说一共有0~3四个特权级,0级最高,3级最低,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查,相关的概念有CPL、DPL和RPL,这里不再过多阐述。硬件已经提供了一套特权级使用的相关机制,软件自然就是好好利用的问题,这属于操作系统要做的事情,对于Unix/Linux来说,只使用了0级特权级和3级特权级。也就是说在Unix/Linux系统中,一条工作在0级特权级的指令具有了CPU能提供的最高权力,而一条工作在3级特权级的指令具有CPU提供的最低或者说最基本权力。 3)用户态和内核态

OS学习记录:线程

北战南征 提交于 2020-02-07 13:18:47
线程:   线程的实质是把进程的任务划分成更小、不能再分、具有独立功能的单位,以线程的形式来并发执行,以提高程序并发执行的程度。   线程是进程中的一个实体,是被系统独立调度和分派的基本单位。线程只拥有在运行必需的资源,包括程序计数器,一组寄存器和栈,但它可与同属一个进程的其他线程共享线程所拥有的全部资源。一个线程可以创建和撤销另一个线程。同一个进程的多个线程可以并发执行。线程在运行中呈现间断性,也有就绪、阻塞和运行三种基本状态。   线程的分类:     (1)内核级线程       内核级线程依赖于内核。用户进程和系统进程中的线程的创建、撤销和切换都由内核实现,在内核中保留每个线程的控制块,内核根据该控制块感知线程的存在并对线程进行控制。    (2)用户级进程       用户级进程不依赖于内核,与内核无关,线程的创建、撤销、切换都不需要利用系统调用实现。   线程的区别:     (1)线程的调度与切换速度        内核级线程的调度由内核的线程调度程序完成,用户级线程则由用户线程包中的一个过程来完成。内核级线程的调度程序在核心态下运行。用户级线程的调度程序在用户态下运行。        内核级线程的调度规则与进程调度相似,用户级线程的调度规则相对简单;内核级线程切换慢,用户级线程切换块。     (2)系统调用        内核级线程进行系统调用只阻塞该线程

linux系统调用进程2信号

人盡茶涼 提交于 2020-02-06 22:37:44
1. 信号理论基础 **信号共性: 简单、不能携带大量信息、满足条件才发送 **信号的特质: 信号是软件层面上的"中断"。一旦型号产生,无论程序执行到什么位置,必须立即停止运行,处理信号,处理结束,在继续执行后续指令。 所有信号的产生以及处理全部都是有【内存】完成的 *** 信号产生 1. 按键产生,ctrl+z、ctrl+c 2. 系统调用产生, 如果kill 3. 软件条件产生, sleep 4. 硬件异常产生, 段错误、 段错误: 1. 访问了不是自己内存, 比如malloc自己申请了区域,访问malloc区域外了 2. 对只读区进行修改 char* ch="abc" ch[0]='a' 5.命令产生,比如kill命令 未决: 产生与递达之间状态 递达: 产生送到内核,直接被内核处理掉 信号处理方式: 默认、忽略、捕捉(自定义) linux内核进程控制块pcb是一个结构体,task_struct,除了包含进程id,状态,工作目录,用户id,组id,文件描述符表, 还包含信号相关信息,阻塞信号和未决信号 例子: 比如ctrl+c发送2号信号,那么未决信号集把第二位设置为1,那么内核发现第二未变成1了,处理2号信号,处理[默认、忽略、捕捉(自定义)]完毕第二位变成0 未决信号集把第二位设置为1 完毕第二位变成0 如果由于某种原因,把2号信号设置屏蔽,那么信号屏蔽字中2号变成1

文件io和标准io的联系

核能气质少年 提交于 2020-02-06 06:13:47
 linix对IO文件的操作分为不带缓存的IO操作(文件IO都是不带缓存IO)和带缓存的标准IO操作.   刚开始,要明确以下几点:    不带缓存,其实不是直接对磁盘文件进行读取操作 ,像read()和write()函数,它们都属于系统调用,只不过在用户层没有缓存,所以叫做无缓存IO,但对于内核来说,还是进行了缓存,只是用户层看不到罢了。 1.  linux的文件I/O是一种低级的I/O,由操作系统提供的基本IO服务。(底层)    而标准I/O是ANSIC建立的一种标准I/O模型,是一种标准函数包和stdio.h头文件中的定义,具有一定的可移植性。(标准库封装) 2.   标准I/O默认采用了缓冲机制,还创建了一个包含文件和缓冲区相关数据的数据结构。       文件I/O一般没有采用缓冲模式,需要自己创建缓冲区。 3.  所有I/O函数都是针对文件描述符的。当打开一个文件时,即返回一个文件描述符,然后该文件描述符就用于后续的I/O操作。    而对于标准I/O库,它们的操作则是围绕流进行的。当用标准I/O库打开或创建一个文件时,我们已使用一个流与一个文件相关联。 4.   标准的 C 库函数(标准io)建立在底层系统调用(文件io)之上 ,即 C 函数库文件访问函数的实现中使用了文件 I/O 系统调用。    标准的 C 库中的文件处理函数为了减少使用系统调用的次数,提高效率

I/O 模型

拜拜、爱过 提交于 2020-02-05 10:53:49
5种I/O模型的基本区别: 阻塞式I/O 非阻塞式I/O I/O复用 信号异步模型 异步I/O 1. 阻塞 I/O 最流行的I/O模型是阻塞I/O模型,缺省情形下,所有套接口都是阻塞的。 我们以数据报套接口为例来讲解此模型(我们使用UDP而不是TCP作为例子的原因在于就UDP而言,数据准备好读取的概念比较简单:要么整个数据报已经收到,要么还没有。然而对于TCP来说,诸如套接口低潮标记等额外变量开始活动,导致这个概念变得复杂)。进程调用recvfrom,其系统调用直到数据报到达且被拷贝到应用进程的缓冲区中或者发生错误才返回,期间一直在等待。我们就说进程在从调用recvfrom开始到它返回的整段时间内是被阻塞的。 2. 非阻塞 I/O 进程把一个套接口设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠才能完成时,不要把本进程投入睡眠,而是返回一个错误。也就是说当数据没有到达时并不等待,而是以一个错误返回。 3、I/O复用模型 调用select或poll,在这两个系统调用中的某一个上阻塞,而不是阻塞于真正I/O系统调用。 阻塞于select调用,等待数据报套接口可读。当select返回套接口可读条件时,调用recevfrom将数据报拷贝到应用缓冲区中。 4、信号驱动式I/O模型 首先开启套接口信号驱动I/O功能, 并通过系统调用sigaction安装一个信号处理函数

Linux进程同步机制-Futex

纵然是瞬间 提交于 2020-02-05 02:43:21
引子 在编译2.6内核的时候,你会在编译选项中看到[*] Enable futex support这一项,上网查,有的资料会告诉你"不选这个内核不一定能正确的运行使用glibc的程序",那futex是什么?和glibc又有什么关系呢? futex诞生之前 在futex诞生之前,linux下的同步机制可以归为两类:用户态的同步机制 和 内核同步机制。 用户态的同步机制基本上就是利用原子指令实现的spinlock。最简单的实现就是使用一个整型数,0表示未上锁,1表示已上锁。trylock操作就利用原子指令尝试将0改为1: bool trylock ( int lockval ) { int old ; atomic { old = lockval ; lockval = 1 ; } // 如:x86下的xchg指令 return old == 0 ; } spinlock的lock操作则是一个死循环,不断尝试trylock,直到成功。 对于一些很小的临界区,使用spinlock是很高效的。因为trylock失败时,可以预期持有锁的线程(进程)会很快退出临界区(释放锁)。所以死循环的忙等待很可能要比进程挂起等待更高效。 但是spinlock的应用场景有限,对于大的临界区,忙等待则是件很恐怖的事情,特别是当同步机制运用于等待某一事件时(比如服务器工作线程等待客户端发起请求)

操作系统--Linux线程

 ̄綄美尐妖づ 提交于 2020-02-05 00:04:49
Linux内核在2.2版本中引入了线程机制。Linux提供了fork,这是具有传统进程复制功能的系统调用。Linux还提供了系统调用clone,其功能类似于创建一个线程。clone与fork的行为类似,它不是创建调用进程的复制,而是创建一个独立进程以共享原来调用进程的地址空间。通过共享父进程的地址空间,clone任务能像独立线程一样工作。 由于Linux 内核进程的特定表示方式,所以允许共享地址空间。系统内的每个进程都有一个唯一的内核数据结构。不过,该数据结构并不保存该数据结构中进程本身的数据,而是保存了此数据保存出的数据结构的指针。例如每个进程的数据结构都包括其他数据结构(如表示打开文件列表、信号处理信息和虚拟内存等)的指针。当调用fork时,就创建了新进程,它具有父进程的所有相关数据结构的拷贝。当调用clone时,也创建了新进程。但是,新进程并不是复制所有数据结构,而是指向了父进程的数据结构,从而允许子进程共享父进程的内存和其他进程资源。作为系统调用clone 的参数,可传递一些标记的集合,这个标记集用来指出父进程有多少内容被子进程共享了。如果没有设置标记,那么就没有共享且clone与fork一样动作。如果设置了所有五个标记,那么子进程与父进程就共享了一切。其他不同标记的组成形成了这两极之间的不同程度的共享。 有趣的是,Linux并不区分进程和线程。事实上

操作系统

两盒软妹~` 提交于 2020-02-04 17:39:45
为什么要有操作系统? 现代计算机系统是一个复杂的系统,主要由处理器,内存,硬盘,键盘,鼠标,网络接口及其他输入输出设备组成。程序员无法把所有的硬件操作细节都了解到,管理这些硬件并且加以优化使用是非常繁琐的工作,这个繁琐的工作就是由操作系统来完成的,有了他,程序员从繁琐的工作中解脱出来,只需要考虑自己应用软件的编写就可以了,应用软件直接使用操作系统提供的接口来操作硬件。 什么是操作系统? 操作系统,位于计算机硬件与应用软件之间,是一个协调,管理和控制计算机硬件资源和软件资源的控制程序,本质也是一个软件。由操作系统的内核(内核态,管理硬件资源)以及系统调用(运行于用户态,为应用程序提供系统调用的接口)组成。          操作系统的功能? 隐藏丑陋的硬件调用接口,为应用程序提供更好,更简单,更清晰的系统调用接口。有了这些接口之后,就不用再考虑操作硬件的细节,专心开发自己的应用程序即可。   例如:操作系统提供了文件这个抽象概念,对文件的操作就是对硬盘的操作,有了文件我们就不需要再去考虑关于磁盘的读写控制了。 将应用程序对硬件资源的竞态请求变得有序化。操作系统可以同时运行多个程序,程序之间会互相竞争资源(硬件,cpu,内存等),操作系统会对处理器,存储器以及其他I/O接口设备的分配   例如:计算机上同时运行三个打印程序,它们想在同一时刻在同一计算机上输出结果,输出的结果最终会一团糟