分类: LINUX
2011-06-25 11:36:23
(图片没有出来,给大家个链接
http://blog.csdn.net/wanxiao009/archive/2010/06/04/5648583.aspx
)
学习linux编程,首先要学会使用shell,这里一些基础命令就不介绍了。这里唯一要提的一个shell命令就是man。man是任何一个开发者都应该学会经常使用的工具,使用man比去查看任何一本教材都要来的快速准确。man可以查看一下内容:
1.一般命令(shell命令)
2.系统调用(open write等直接陷入内核的函数)
3.子函数(C函数库等不直接陷入内核的函数)
4.特殊文件(/dev/zero等linux系统中有特殊用途的文件)
5.文件格式(linux系统的配置文件格式 host.conf)
6.游戏
7.宏和地方传统定义(本地配置)
8.维护命令(tcpdump等用来观察linux系统运行情况的命令)
IO分为有缓冲IO和无缓冲IO两种,具体的区别可以见下图。不带缓冲的I/O,直接调用系统调用,速度快,如函数open(), read(), write()等。而带缓冲的I/O,在系统调用前采用一定的策略,速度慢,比不带缓冲的I/O安全,如fopen(), fread() fwrite()等。
下面介绍文件IO中的基础函数。
1.open函数
open函数:调用它可以打开或者创建一个文件。
flags 可选选项:
O_APPEND 以追加方式打开文件,每次写时都写在文件末尾。
O_CREAT 如果文件不存在,则创建一个,存在则打开它。
O_EXCL 与O_CREAT一起使用时,如果文件已经存在则返回出错。
O_TRUNC 以只写或读写方式打开时,把文件截断为0
O_DSYNC 每次write时,等待数据写到磁盘上。
O_RSYNC 每次读时,等待相同部分先写到磁盘上。
O_SYNC 每次write时,等到数据写到磁盘上并接更新文件属性。
SYNC选项都会影响降低性能,有时候也取决于文件系统的实现。
mode 只有创建文件时才使用此参数,指定文件的访问权限。模式有:
S_IRWX[UGO] 可读 可写 可执行
S_IR[USR GRP OTH] 可读
S_IW[USR GRP OTH] 可写
S_IX[USR GRP OTH] 可执行
S_ISUID 设置用户ID
S_ISGID 设置组ID
U->user G->group O->others
2.creat函数
creat 以只写方式创建一个文件,若文件已经存在,则把它截断为0
3.close函数
close 关闭已经打开的文件,并释放文件描述符
如果失败,返回值为-1
当一个进程结束时,操作系统会自动释放该进程打开的所有文件。但还是推荐用close来关闭文件。
lsof命令可以查看进程打开了那些文件。
4.lseek函数
lseek 用来定位当前文件偏移量,既你对文件操作从文件的那一部分开始。
5.read函数
read 从当前文件偏移量处读入指定大小的文件内容
6.write函数
write向一个文件写入一定字节的内容。
以上都是文件IO最基本的几个函数,那么linux的IO是怎么实现的呢?内核使用了三种数据结构,来实现I/O
1. 每个进程在进程表中都有一个记录项,每个记录项中有一张打开文件描述符表,可将其视为一个矢量,每个描述符占用一项。与每个 文 件描述符相关联的是:
(a) 文件描述符标志。
(b) 指向一个文件表项的指针。
2. 内核为所有打开文件维持一张文件表。每个文件表项包含:
(a) 文件状态标志(读、写、增写、同步等)。
(b) 当前文件位移量。
(c) 指向该文件v节点表项的指针。
3. 每个打开文件(或设备)都有一个v节点结构。v节点包含了文件类型和对此文件进行各种操作的函数的指针信息。对于大多数文件, v节点还包含了该文件的i节点(索引节点)。例如, i节点包含了文件的所有者、文件长度、文件所在的设备、指向文件在盘上所使用的实际数据块的指针等等
如下图所示,内核中的数据结构
两个文件各自打开同一个文件,它们拥有各自的文件表项,但共享v节点表。见下图所示
什么是原子操作?
A B两个进程以O_APPEND方式打开同一个文件。A 进程去写该文件,假设此时文件偏移量为1000,B进程同时去写该文件,此时由于A进程未写完,则B进程得到的文件偏移量仍为1000。最后B进程的内容可能会覆盖掉A进程写的内容。pread , pwrite是原子读写操作。相当于先把文件偏移量定位到offset,然后在进行读写。这都是一步完成,不存在竞争问题。
下面介绍一些文件IO中比较高级的函数。dup(),fcntl(),sync()等。
1.dup函数
dup/dup2用来复制一个已经存在的文件描述符
2.fcntl函数
fcntl 可以改变已经打开的描述符。
3.sync函数
最后些一个测试程序,希望可以用到里面大多数函数,用于测试其功能。这个程序功能是打开一个文件,在里面写入hello world,然后调用dup函数复制一个文件描述符,随后调用lseek将偏移量设置到hello之后,最后读出文件内容world打印到终端显示。代码如下所示