版权归原作者所有,如有侵权,请联系我们

[科普中国]-排斥调用

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

简介

在计算机系统中,通常运行着两类程序:系统程序和应用程序,为了保证系统程序不被应用程序有意或无意地破坏,为计算机设置了两种状态:系统态(也称为管态或核心态)和用户态(也称为目态)。操作系统在系统态运行,而应用程序只能在用户态运行。

调用一般分为系统调用和一般调用。一般的过程调用,其调用程序和被调用程序都运行在相同的状态——系统态或用户态;而系统调用与一般调用的最大区别就在于:调用程序是运行在用户态,而被调用程序是运行在系统态。排斥调用即调用的程序或函数之间是互斥的,它们之间一次只有一个能执行,在一般调用和系统调用过程都有存在。不过排斥调用主要发生在系统调用过程中,这这与计算机的资源有关。

系统调用系统调用(英语:system call),又称为系统呼叫,指运行在使用者空间的程序向操作系统内核请求需要更高权限运行的服务。系统调用提供用户程序与操作系统之间的接口。大多数系统交互式操作需求在内核态执行。如设备IO操作或者进程间通信。

由于各 OS 的性质不同,在不同的 OS 中所提供的系统调用之间也会有一定的差异。对于一般通用的 OS 而言,可将其所提供的系统调用分为:进程控制、文件操纵、通信管理和系统维护等几大类。

进程控制类系统调用这类系统调用主要用于对进程的控制,如创建一个新的进程和终止一个进程的运行,获得和设置进程属性等。

文件操纵类系统调用对文件进行操纵的系统调用数量较多,有创建文件、删除文件、打开文件、关闭文件、读文件、写文件、建立目录、移动文件的读/写指针、改变文件的属性等。

进程通信类系统调用在 OS 中经常采用两种进程通信方式,即消息传递方式和共享存储区方式。 当系统中采用消息传递方式时,在通信前,必须先打开一个连接。为此,应由源进程发出一条打开连接的系统调用 open connection,而目标进程则应利用接受连接的系统调用 accept connection表示同意进行通信;然后,在源和目标进程之间便可开始通信。可以利用发送消息的系统调用 send message 或者用接收消息的系统调用 receive message 来交换信息。通信结束后,还须再利用关闭连接的系统调用 close connection 结束通信。用户在利用共享存储区进行通信之前,须先利用建立共享存储区的系统调用来建立一个共享存储区,再利用建立连接的系统调用将该共享存储区连接到进程自身的虚地址空间上,然后便可利用读和写共享存储区的系统调用实现相互通信。1

实现Linux 的系统调用通过 int 80h 实现,用系统调用号来区分入口函数。操作系统实现系统调用的基本过程是:

应用程序调用库函数(API);

API 将系统调用号存入 EAX,然后通过中断调用使系统进入内核态;

内核中的中断处理函数根据系统调用号,调用对应的内核函数(系统调用);

系统调用完成相应功能,将返回值存入 EAX,返回到中断处理函数;

中断处理函数返回到 API 中;

API 将 EAX 返回给应用程序。

应用程序调用系统调用的过程是:

把系统调用的编号存入 EAX;

把函数参数存入其它通用寄存器;

触发 0x80 号中断(int 0x80)。

互斥在逻辑学中,互斥(Mutually Exclusive)是一种逻辑关系,指几个变量或事件之中的任一个不可能与其它一个或多个同时为真,或同时发生的情况。对于逻辑函数,其变量互斥,意味着两个以上变量为真(包括都不为真)的情况会导致函数值为假。对于事件,其所有条件的互斥意味着,任两个条件的实现都将阻止事件的产生。同样可以引申到程序编写及其它关系。

比如一个最简单的情况下,投掷一枚硬币,硬币不可能同时出现既为正也为反;两个结果互斥。

示例Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。

request和response对象既然代表请求和响应,那我们要获取客户机提交过来的数据,只需要找request对象就行了。要向客户机输出数据,只需要找response对象即可。

HttpServletResponse对象服务器的响应。这个对象中封装了向客户端发送响应状态码(即响应行)、发送响应头、发送数据的方法。

查看servlet文档的HttpServletResponse中主要方法有:

setStatus() // 发送状态码

setHeader() //发送响应头

getWriter() //发送字符流数据,从父对象继承的方法,Servlet程序可以按字符形式输出响应正文。

getOutputStream() //发送字节流数据,从父对象继承的方法,字节流可以写任何数据,但是字符流只能写字符串。比如电影只能通过字节流写出。2

其中getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 getOutputStream方法返回的字节输出流对象的类型为ServletOutputStream,它可以直接输出字节数组中的二进制数据。 getWriter方法将Servlet引擎的数据缓冲区包装成PrintWriter类型的字符输出流对象后返回,PrintWriter对象可以直接输出字符文本内容。 Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。 Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。