操作系统或计算机网络用语范畴。是由若干条指令组成的,用于完成一定功能的一个过程。primitive or atomic action 是由若干个机器指令构成的完成某种特定功能的一段程序,具有不可分割性·即原语的执行必须是连续的,在执行过程中不允许被中断。
中断、异常和系统调用的关系 1.中断的概念
中断是CPU的一个功能,就是;
CPU停下当前的工作,
- 保留现场后
- 自动地转去执行相应的处理程序,
- CPU控制权发生改变
- 处理完该事件后再返回断点继续执行被刚才被打断的程序。
a.编程异常通常叫做软中断(空指针,数组越界,classnotfound)
b.软中断是通讯进程之间用来模拟硬中断的 一种信号通讯方式。
c.中断源发中断请求或软中断信号后,CPU或接收进程在适当的时机自动进行中断处理或完成软中断信号对应的功能
d.软中断是软件实现的中断,也就是程序运行时其他程序对它的中断;而硬中断是硬件实现的中断,是程序运行时设备对它的中断。
硬中断:a.硬中断是由外部事件引起的因此具有随机性和突发性(断电);软中断是执行中断指令产生的,无面外部施加中断请求信号,因此
中断的发生不是随机的而是由程序安排好的。
b.硬中断的中断响应周期,CPU需要发中断回合信号(NMI不需要),软中断的中断响应周期,CPU不需发中断回合信号。
c.硬中断的中断号是由中断控制器提供的(NMI硬中断中断号系统指定为02H);软中断的中断号由指令直接给出,无需使用中断控制器。
d.硬中断是可屏蔽的(NMI硬中断不可屏蔽),软中断不可屏蔽。
区别:
a.软中断发生的时间是由程序控制的,而硬中断发生的时间是随机的
b.软中断是由程序调用发生的,而硬中断是由外设引(在输入文本的时候拔掉键盘)发的
c.硬件中断处理程序要确保它能快速地完成它的任务,这样程序执行时才不会等待较长时间
2.2可屏蔽中断和不可屏蔽中断
2.3中断可分为三类:
- 第一类是由CPU外部引起的,称作中断,如I/O中断、时钟中断、控制台中断等。
- 第二类是来自CPU的内部事件或程序执行中的事件引起的 过程,称作异常,如由于CPU本身故障(电源电压低于105V或频率在47~63Hz之外)、程序故障(非法操作码、地址越界、浮点溢出等)等引起的过程。
- 第三类由于在程序中使用了请求系统服务的系统调用而引发的过程,称作“陷入”(trap,或者陷阱)。前两类通常都称作中断,它们的产生往往是无意、
被动的,而陷入是有意和主动的。
第一类(中断)+第二类(异常)= 中断
第三类(系统调用)= 系统调用
系统调用:由操作系统实现提供的所有系统调用所构成的集合即程序接口或应用编程接口(Application Programming Interface,API)。是应用程序同系统之间的接口。
就是执行一个系统调用指令,将控制权将目态转为管态;任何单 CPU 计算机一次只能执行一条指令。如果一个进程正在用户态运行一个程序,并且需要一个系统服务,比如从一个文件读取数据,那么它就必须执行一个陷阱(trap)或系统调用指令,将控制转移到操作系统。操作系统接着通过参数检查找出所需要的调用进程。
然后,它执行系统调用,并把控制返回给系统调用后面跟随着的指令。在某种意义上,进行系统调用就像进行一个特殊的过程调用,但是只有系统调用可以进入内核,而过程调用不能。
一般把系统调用的编号放在操作系统所期望的地方,如寄存器中。然后执行一个 trap 指令,将用户态切换到内核态,并在内核中的一个固定地址开始执行。TRAP 指令实际上与过程调用指令非常类似,它们后面都跟随着一个来自远处位置的指令,以及供以后使用的一个保存在栈中的返回地址。
然而,trap 指令与过程指令存在两个方面的差别。首先,它的副作用是,切换到内核态。而过程调用指令并不改变模式。其次,不像给定过程所在的相对或绝对地址那样,trap 指令不能跳转到任意地址上。根据机器的体系结构,或者跳转到一个单固定地址上,或者指令中有一8位长的字段,它给定了内存中一张表格的索引,这张表格中含有跳转地址。
跟随在 trap 指令后的内核代码开始检查系统调用编号,然后分派给正确的系统调用处理器,这通常是通过一张由系统调用编号所引用的、指向系统调用处理器的指针表来完成。此时,系统调用处理器运行。一旦系统调用处理器完成其工作,控制可能会在跟随 trap 指令后面的指令中返回给用户空间库过程。这个过程接着以通常的过程调用返回的方式,返回到用户程序。
为了完成整个工作,用户程序还必须清除堆栈,如同它在进行任何过程调用之后一样。假设堆栈向下增长,如经常所做的那样,编译后的代码准确地增加堆栈指针值。在这之后,原来的程序就可以随意执行了。
系统调用和过程调用- 状态切换:系统调用要进行状态切换,由用户态切换到系统态;过程调用只需要在用户态就能完成
- 速度效率:系统调用反应快 直接通过内存访问 而过程调用是要从硬盘中提取数据 速度所以没系统调用快
常见系统调用
进程管理
pid=fork() 创建一个与父进程相同的子进程
pid=waitpid(pid, &statloc, options) 等待一个子进程终止
s=execve(name, argv, environp) 替换一个进程的核心映像
exit(status) 终止进程执行并返回状态
文件管理
fd=open(file, how, ...) 打开一个文件供读、写或两者
s=close(fd) 关闭一个打开的文件
n=read(fd, buffer, nbytes) 把数据从一个文件读到缓冲区中
n=write(fd, buffer, nbytes) 把数据从缓冲区写到一个文件中
position=lseek(fd, offset, whence) 移动文件指针
s=stat(name, &buf) 取得文件的状态信息
目录和文件系统管理
s = mkdir(name, mode) 创建一个新目录
s = rmdir(name) 删去一个空目录
s = link(name1, name2) 创建一个新目录项 name2,并指向 name1
s = unlink(name) 删去一个目录项
s = mount(special, name, flag) 安装一个文件系统
s = umount(special) 卸载一个文件系统
杂项
s = chdir(dirname) 改变工作目录
s = chmod(name, mode) 修改一个文件的保护位
s = kill(pid, signal) 发送信号给一个进程
seconds = time(&seconds) 自 1970 年 1 月 1 日 起的流逝时间
用于进程管理的系统调用
在 UNIX 中,fork 是唯一可以在 POSIX 中创建进程的途径。它创建一个原有进程的精确副本,包括所有的文件描述符、寄存器等内容。在 fork 之后,原有的进程及其副本(父与子)就分开了。在 fork 时,所有的变量具有一样的值,虽然父进程的数据被复制用以创建子进程,但是其中一个的后续变化并不会影响到另一个。(由父进程和子进程共享的程序正文,是不可改变的。)fork 调用返回一个值,在子进程中该值为 0,并且在父进程中等于子进程的进程标识符(Process IDentifier,PID)。使用返回的 PID,就可以在两个进程中看出哪一个是父进程,哪一个是子进程。
多数情形下,在 fork 之后,子进程需要执行与父进程不同的代码。这里考虑 shell 的情形。它从终端读取命令,创建一个子进程,等待该子进程执行命令,在该子进程终止时,读入下一条命令。为了等待子进程结束,父进程执行 waitpid 系统调用,它只是等待,直至子进程终止(若有多个子进程的话,则直至任何一个子进程终止)。waitpid 可以等待一个特定的子进程,或者通过将第一个参数设为 -1 的方式,等待任何一个老的子进程。在 waitpid 完成之后,将把第二个参数 statloc 所指向的地址设置成子进程的退出状态。有各种可用的选项,它们由第三个参数确定。
现在考虑 shell 如何 fork。在键入一条命令后,shell 调用 fork 创建一个新的进程。这个子进程必须执行用户的命令。通过使用 execve 系统调用可以实现这一点,这个系统调用会引起整个核心映像被一个文件所替代,该文件由第一个参数给定。(实际上,该系统调用是 exec 系统调用,但是若干个不同的库过程使用不同的参数和稍有差别的名称调用该系统调用。