文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>系统调用和标准I/O库(编写中)

系统调用和标准I/O库(编写中)

时间:2007-02-05  来源:coolcoco

本文介绍了两个相同功能的程序,复制一个大小为1m的文件,以此观察系统调用和I/O库函数的不同操作和对系统性能的影响

首先是利用系统调用,系统调用是比较底层的使用,比较靠近硬件,需要自己处理缓冲区。来看看代码,保存成copy_system.c,同时目录下还需要有一个大约为1MB大小的file.in文件
CODE:

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main()
{
       char c;
       int in, out;
       in = open("file.in", O_RDONLY);
       out = write("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
       
       while(read(in, &c, 1) == 1)
               write(out, &c, 1);

       exit(0);
}
[Copy to clipboard]
这里不会叙述C语言的细节,所以有关指针等的操作请自己查阅其他资料,这里只谈何系统调用和I/O库函数操作有关的东西

首先是包含了一系列头文件,这些是系统调用read、write所必需的。然后分别声明了一个字符变量,用于放置临时的字符。 两个整形变量用于作为文件标示符,因为在系统调用中,read和write都会利用一个叫文件标示符的东西把要写入或是读取的东西和一个文件或者一个设备管理起来,这样就可以让用户不用和底层的东西打交道。当然在读写之前都需要有文件操作,那么需要系统调用open

接下来看看这三个系统调用的原形
CODE:


#include <unistd.h>
size_t write(int fildes, const void *buf, size_t nbytes);

size_t read(int fildes, const void *buf, size_t nbytes);

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode);
[Copy to clipboard]

系统调用write的作用就是把缓冲区buf中的东西写入fildes所指定的文件或者设备中去,返回的数值是实际写出的字节数。而read则相反。open则是返回一个可以操作的文件标示符,供以后使用,其中path是文件的路径,分别代表了标准的输入和标准的输出。oflags是一个标志位,告诉程序怎么访问文件,有三种模式:O_RDONLY, O_WRONLY, O_RDWR,分别是只读、只写和读写。最后一个是模式标志位,用于设置文件的权限,这个不详细说明。

那么再回到上面的程序,程序开启了一个名为“file.in"的文件,将其标示符传给in,并且是只读方式。同样开辟了一个名为“file.out”的文件,把其标示符传递给out,是只写方式,设置权限为用户具备读和写的权限,组和其他人员均没有配置权限。

然后开始在文件中作循环,检测是否到达文件末尾,如果没有则反复地从file.in中提取字符写入file.out

使用linux自带的性能测试time看下运行的时间
CODE:

$time ./copy_system
[Copy to clipboard]
在我的系统上大约经过了14s才运行完,而且期间CPU占用率几乎为100%,说明底层调用对系统资源开销很大。它采用了一种类似于流水线的作业方式

我们再看另外一种改进的系统调用
CODE:

#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main()
{
       char block[1024];
       int in, out;
       int nread;
       in = open("file.in", O_RDONLY);
       out = write("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
       
       while((nread = read(in, block, sizeof(block))) >0)
               write(out, &c, 1);

       exit(0);
}
[Copy to clipboard]

这里设定了一个为1024bit的缓冲区,如果缓冲区满了才进行系统调用,那么我们可以比较出这个程序大概使用了2000次系统调用,而前者则使用了大约两百万次的系统调用,可见可以通过一些方法进行优化。这个程序在我的系统上运行仅用了0.083s,性能有很大的提高。

排行榜 更多 +
摧毁大厦游戏

摧毁大厦游戏

飞行射击 下载
合并动物城手游版

合并动物城手游版

休闲益智 下载
哈士奇大冒险

哈士奇大冒险

休闲益智 下载