UNIX操作系统系统调用和缓冲区

       UNIX操作系统也是一种程序。由操作系统内核管理着操作系统的各种资源,如CPU、内存,网络、设备、定时器、进程管理、进程间通信等(socket也是一种系统资源,提供了多系统之间进程的通信机制)。

        操作系统和内核运行在系统空间,每个普通的用户会单独的给其分配对应的用户空间,但用户没有权限去直接调用系统资源,需要通过内核来调用。内核统一的管理着所有的系统资源,这样才不会在一个多用户和很多进程的系统程序中搞乱资源的分配!
        比如文件的读取,磁盘只可以被内核直接访问,用户程序想要读取磁盘上的数据只能通过系统调用的方式(使用read函数)由内核来完成。read的代码在内核中,所以每次read被调用的时候,代码的执行权限都会从用户转向内核,读取完以后再从内核转交给应用程序!
       当运行系统调用的内核代码read的时候,cpu需要超级用户模式,需要一些特殊的堆栈和内存环境,必须在系统调用的时候建立好。read结束后,cpu再次切换为用户模式,把堆栈和内存环境恢复成之前用户程序的时候的状态。文件读取的时候系统先用read把文件从磁盘读取的内核缓冲区(读取磁盘的时候也是有缓冲的,为了提高磁盘的读取性能),接着把文件从内核缓冲区复制到用户的进程缓冲区(从内核空间到用户空间的一个转换)。
       用户代码在调用的时候还可以人为的设置个缓冲区,比如读取文件的时候一次更多的读取(比如比如一次读取4096个字节这种方式)可以减少这种不同的工作模式的切换,在read和write操作的时候合理的使用自己的缓冲区减少系统调用能够大大的提升程序执行的效率!

      内核在从磁盘读取文件的时候为了提高IO效率也会使用缓冲区的这种技术,叫做内核缓冲区,每次内核在从磁盘读取的时候一次会读取更多保存在内核缓冲区,当用户的进程需要从磁盘上的文件中读取数据的时候,首先是从内核缓冲区中读取数据,当数据不够读取的时候内核再次从磁盘读取数据到缓冲区。而且读取的也不是只够这次使用就行,而是读取更多的数据再次保存到内核缓冲区中。每次当进程要读取的数据块不在内核缓冲区中的时候,就把读取相应的数据的请求加入到请求列表,然后挂起进程,接着处理其他进程服务。

       read把数据从内核缓冲区复制到进程缓冲区,write把数据从进程缓冲区复制到内核缓冲区,但是并不是read的时候一定会内核从文件读取,同样write的时候也未必内核会立即向文件写入。并不是所有的write操作都会触发内核的写入文件的操作,内核会把数据放入内核缓冲区,当数据足够多的时候再一次写入到文件上去。如果此时突然断电可能就会导致内核的数据还未写入到磁盘的情况发生。不过据说freebsd操作系统在文件读写上是同步的,磁盘IO性能也略低于其他的系统,这个就需要去了解FreeBSD的磁盘读写了。

       继续说系统调用,系统调用的时候其实就是一种状态的切换,保存当前堆栈和内存信息然后挂起进程等待系统调用的返回结果,然后回来后恢复堆栈和内存然后继续执行自己的代码。

参考文档:UNIX网络编程

你可能感兴趣的:(linux)