UNIX的高级编程环境_第1页
UNIX的高级编程环境_第2页
UNIX的高级编程环境_第3页
UNIX的高级编程环境_第4页
UNIX的高级编程环境_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1.1文件系统的内部结构 硬件:在硬件上 把磁盘划分为一连串的块,块的大小从512到4096个字节都有可 能,完全依系统而定 文件系统在磁盘上的分布: |引导块|超级块| I节点表|数据块| 1引导块的内容: 文件系统的大小 可供使用的存储块的总数以及可供使用的块所组成的连接列表 超级块是否被修改过,修改过,当核心程序执行sync指令时,会把主存中的超 级块写回磁盘里 文件系统与磁盘的逻辑名称 可供使用的I节点总数及能够使用的I节点所组成的连接列表 最近一次I节点被修改的时间 2.i节点的内容: 文件的存取权限(用一个16位的字段表示) 位元 符号常数 含义 15 S IFREG 一般文件 1

2、4 S IFDIR 目录 13 S IFCHR/S IFBLK 字符或块设备 12 S IFIC 命名管道 11 S ISUID 用户标识符是否被设定 10 S ISGID 用户组标识符是否被设定 9 S ISVTX 是否被置换 08 Rwx-rwx-rwx 文件存取权限 注:其中12位到15位是用来判别文件类别,它们在文件建立时就已经设定 完成,而且不能被更改 S_ISUID:当一个文件被建立时,文件的用户标识符(user ID)与用户组标符 (group ID)被系统设置当一个用户签到进入 UNIX系统时,其用户标识符 (user ID)与用户组标识符(group ID)被系统设置,当一个

3、文件被执行时,该 进程会被给定两个标识符:真实用户标识符与有效用户标识符其中真实 用户标识符为文件的用户标识符,有效用户标识符随 S_ISUID的不同的 设定而不同其中如S_ISUID为off,则有效用户标识符与真实用户标识 符相同如 S_ISUID为on,则有效用户标识符为运行该文件的用户的用户 标识符有效用户标识符标识的用户享有与真实用户标识符标识的用户相 同的权利例如:真实用户标识的用户对文件拥有读写的权利,则有效用户 标识的用户也对该文件享有读写的权利在系统中,S_ISUID能设为on的 文件不能超过50个 S_ISUID的设定:chmod rwsrwxrwx 第三位不是 x而设为s

4、S_ISGID同S_ISUID,但是指用户组 S_ISGID的设定:chmod rwxrwsrwx 第六位不是 x而设为s S_ISVTX(是否被置换):当该位被置为1时,该文件被装入内存后,形同 DOS的TSR程序,将常驻内存 S_ISVTX的设定:chmod rwtrwxrwx 第三位不是t而设为s 文件存取权限的设置: 格式一 :rwxrwxrwx 格式二 : 八进制 意义 0400 允许文件主读 0200 允许文件主写 0100 允许文件主执行 0040 允许组读 0020 允许组写 0010 允许组执行 0004 允许其它人读 0002 允许其它人写 0001 允许其它人执行 040

5、00 同 S ISUID 02000 同 S ISGID 01000 同 S ISVTX 注:设置时用其中的八进制数相加值进行设置即可 如0400+0200=0600即为文件主可读写 文件的所有者标识 文件的实际存储地址 文件的存取时间:最近被修改的时间,指文件最近一次被写入或删除数据 的时间 最近被访问的时间,指最近一次被访问的时间 最近文件模式被更改的时间,指I节点的内容被修改的 时间会影响到I节点的指令有 chmod,chown等 文件有多少个连接 文件的大小 文件的类型:一般文件,目录文件,字符设备,块设备和FIFO(命名管道). 3内存中的I节点,内存中的I节点除保留了文件中的I节点

6、的内容外,还会增加四 项数据: I节点被存取的状态,比如I节点被锁定或明或I节点被修改过 有多少个进程在使用该文件及其I节点 现在文件指针所指的位置换言之,下批数据将由此开始读入 I节点所在的磁盘设备标识符(device ID) 4如何通过I节点表索引文件在磁盘上的位置(略) 1.2文件系统调用 类型 函数 用途 文件基本操作 Ope n 打开文件 Creat 建立并打开文件 Close 关闭文件 Read 读文件 Write 写文件 lseek 移动文件指针 fcntl 读取并控制文件的信息 文件存取权限的改变 Access 查看文件的存取权限 Chmod 改变文件的存取权限 Chow n

7、改变文件的所有者,所属组 文件链接操作 Li nk 文件链接 Un li nk 删除文件链接 获取文件系统信息 stat 获取文件的系统信息 Fstat 同上 目录操作 chdir 改变当前工作目录 mkdir 建立目录 rmdir 删除目录 mknod 建立目录与特殊文件 chroot 改变文件系统的起点 ftw 扫描当前目录树 文件卷操作 mount 文件系统的装载 unmount 文件系统的卸载 sync 把缓冲区内容送到磁盘 1. #i nclude int fd ; int ope n( char * , int , int ) fd = ope n ( fname , flags

8、, perms ); fname :可以是绝对路径,也可以是相对路径 flags :O_RDONLY 打开文件用于读 O_WRONL Y 打开文件用于只写 O_RDWR 打开文件用于读写 O_APPEND 同 fopen 的” a模式 O_NDELAY立即打开不做任何耽搁 O_TRONC 写入前先删除原有数据 O_CREAT如果该文件不存在,则建立之,并要求给予存取权限参数 Perms O_EXCL如果目的文件已经存在,那么若以写入模式打开该文件 则open()调用失败 O_NOCTTY如果此标志被设定,而打开的文件为设备文件(主要指 终端),则该终端不可以作为调用ope n()系统调用的哪个

9、 进程的控制终端 其中前三项符号常量是互斥的,其余的若以无意义的组合,则系统不做处 理 perm :例如 0666 fd :成功0 -19的整数 失败-1 2. #include int creat(char * , int ) fd = creat( file name , perms ) file name:是指要打开的文件名称 perms :指打开后的文件的存取权限的设置 fd 打开成功后的文件描述符 成功 ,打开后的蛙文件描述符 失败 ,-1 功能 : 1.用 creat 打开的文件只能用于写操作; 2. filename 可以为一个已存在的文件 ,此时 perms 无意义 ,fd 为

10、打开此文件 后的文件句柄 3. 如 filename 为一个不存在的文件 ,则 creat 建立并打开此文件 ,并把该文 件截为空 ,此时 perms 为该文件的存取权限 3. #include int close( int fd ) fd :用 open 或 creat 打开的文件的句柄 creat 成功返回值为 0,失败返回值为 -1 4. #include int num_read = read(int fd,char* buf,int bufsize) int num_write = write(int fd,char* buf,int bufsize) fd: 文件描述字 buf:

11、输入输出缓冲区 bufsize : 每次调用 read/write 时必须读写的字节数量 ,最小值为 1 num_read:如果是0表示EOF,若是-1则指读取过程有误一般情形返回值是读 取的字节总数 (该总数可能小于 bufsize), 不过 EOF 与回车符不算在被 读入字节总数中 num_write: 返回 -1,指写的过程出错 ,否则返回的是写的字节数 (该总数可能小于 bufsize) 补充 :1.如果 write 写入的对象为文本文件时,在遇到换行符时 ,它会输出换行符 与回车符(0D0A),而read的操作在读到换行符与回车符时转换为换行符 2. 通过设定不同的 bufsize

12、可改变读写速度 ,在 stdio.h 中的符号常量 BUFSIZ 是磁盘块的长度 3. write 在进行写操作时仅能覆盖从当前文件指针到bufsize 这么长的一 部分字符 ,文件其余的字符仍然存在 4. 文件在 read/write 操作时 ,系统保留一文件指针指向当前文件操作位置 5. #include long lseek(int fd,long offset,int origin) fd : 文件描述符 offset: 每一读写操作所需移动的距离,这个值可正可负 ,正值向前移 ,负值指向后 移. origin: 当前位置的基点 : 0 当前位置为文件的开头 1 指当前位置为前一个位置

13、加上偏移量 2 当前位置为文件的尾端 返回值 :从文件头到现在正要读写的位置之间的字节总数;失败,返回-1 补充 :1.因为文件的长度可能大于正型变量的值,所以用 long 2. 只有当第三个参数是1 或 2 时,偏移才可以为负值 3. 新的当前位置可超过文件尾,此时对读是没意义的 ;但对于写 ,它将导致 文件的扩展 ,在新位置与原文件尾部之间,在进行读操作时 ,读到的将是 null 字符 (0 x00) 4如打开文件时,存取模式设为只读(O_RDONL Y),则Iseek将不允许当前 位置设定成超过文件尾 5在 unistd.h 中定义了 SEEK_SET(O) , SEEK_CUR(1),

14、SEEK_END(2) 三个 符号常量供参数使用 6. #i nclude int stat=Iink( char *oIdIink ,char *newIink) oldlink : 原文件名 newlink: 新文件名 stat : 成功 , 返回 0 失败 , 返回-1 7. #include int stat=unlink(char *filename) 8. #include int stat=fcntl(int fd,int cmd,int oparg) 9. #include int stat(char *path,struct stat *buf) int fstat(int

15、fd,struct stat *buf) path : 为目标文件的完整路径 fd : 为打开的文件描述符 struct stat /* 磁盘设备的标识符 */ /* 文件 I 节点的值 */ /* 文件存取权限为的设定状态 */ /* 文件有多少个连接 */ /* 文件所有者的用户标识符 */ /* 文件所有者的用户组标识符 */ /* 只有当目标文件是设备文件时本栏才有意 义.它指示该文件所指向设备的标识符*/ /* 文件的长度 ,设备文件长度为0 */ /* 最近一次文件被访问的时间 */ /* 最近一次文件被修改的时间 */ /* 最近一次文件属性被修改的时间 */ dev_tst_d

16、ev; ino_t st_ino; unsign short st_mode; nlink_t st_nlink; uid_t st_uid; gid_t st_gid; dev_t st_rdev; off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; ; 10.#include int stat=access(char *path,int amode ) path : 为完整路径名 ;若无完整路径名 ,则为当前路径 amode : 从 0 到 7. 如图 mode binary code check for 04

17、 100 read 02 010 write 01 001 execute/search 00000existenee(存在) 将04与02按位” OR可得06(110),表示可读写 stat : 成功 0 (表示文件有 amode 指定的属性 ) 失败- 11. #inelude int ehmod(eonst ehar *path,mode_t mode) 补充:1 .文件被打开时 ,不能用 ehmod 改变文件属性 2. 只有文件主与超级用户才有权执行此系统调用 例如 : ehmod( “ /tmp/tdb ” ,0755) 12. #inelude int ehown(ehar *pa

18、th,int uid,int gid) 同 ehmod( ) 13. #inelude int ehdir(ehar *path) path : 目标路径名 补充:1.chdir的调用者必须有目标目录的搜寻权(x为on),否则调用会失败 14. #inelude int rmdir(const char path) #include #include int mkdir(const char *path,mode_t mode) mode : 为将建立的目录的存取权限 2.1 标准 I/O 库 1. 流和 FILE 结构 .流只是一个程序与一个打开文件之间的数据流 .流是数据 ,不是通道 .程

19、序中用一个指向 FILE 结构类型的指针来标识流 ,FILE 的结构如下 : typedef struct _iobuf int _cnt ; unsigned char *_ptr; unsigned char *_base; char _flag; char _file; FILE _file : 当流与一个文件发生关联时 ,用来保存文件描述符 _flag : 含有流的控制信息 ,例如 ,它可以指出流是否已打开用于读,用于 写 ,用于读写 _cnt,_ptr,_base :描述了与打开的流有关的字符缓冲区._base指出这个缓 冲区的开始位置 ;_ptr 指出缓冲区中下一个处理字符的位 置

20、;_cnt指出_ptr所指位置后缓冲区中剩下字符的个数. 缓冲区的长度为 BUFSIZ 个字符 . .对于一个流进行读写的所有数据都要通过缓冲区来传送.如当写数据时 ,只有当 缓冲区满了 ,才向磁盘写数据 ;当读数据时 ,只有缓冲区空了 ,才从磁盘读数据 .以 此来提高读写数据 2.2 标准 I/O 库函数 1. #include FILE *stream ; char *filename , *type ; int retval ; stream = fopen( filename , type ) ; retval = fclose( stream ) ; type 可以取下列基本值 :

21、r : 打开 filename 用于读 ,如该文件不存在 , 调用失败 , 返回 NULL w: 建立 filename 用于写 ,同时它被截为空 a : 打开 filename 用于只写 ,被写入的文件被追加到文件尾部 . 如果文件不存 在,则建立文件用于只写 一个文件也能被打开用于修改 ,即程序能同时对这个文件进行读写操作.但 因为 I/O 库的缓冲机制 ,所以 ,在输出操作后不能立即进行输入操作 ,除非中 间插入 fseek,fflush 或 rewind 操作 . r+ : 打开文件 filename 用于读写 ,如果文件不存在 ,fopen 将失败 w+: 建立 filename,

22、或把它截为空文件 ,并打开它用于修改 a+ : 打开文件用于修改 ,写入的数据被追加到文件尾部 .如果文件不存在 ,它将 被建立并打开用于读写 以上的只能用于字符操作 ,以下的能用于二进制操作 rb , wb , ab , rb+ , wb+ , ab+ stream : 成功 ,为一指向 FILE 的指针 失败 ,返回 NULL(NULL 在 stdio.h 中定义 ) 补充 :1.在进程中 ,fclose 并不是必须的 ,在进程结束时 ,系统将自动关闭打开的文 件 ,并且如调用 exit( ), 则将缓冲区的内容自动写到磁盘上 ;如不调用 exit, 则此时在缓冲区的内容不会被写到磁盘上

23、2. 在进程中如调用了 fopen( ),为了安全性 , 则结束时 ,必须调用 fclose( )或 exit( ); 2. #include FILE *stream; int retval ; retval = fflush( stream ) ; retval : 成功 ,返回 0 失败 ,返回 EOF(EOF 在 stdio.h 中定义 ,表示文件结束 ) 补充 :1.调用该函数后 ,不管缓冲区是否满 ,将立即把缓冲区的内容写到文件中 3. #include FILE *inf , *outf ; int c ; c = getc( inf ) ; putc( c , outf) c

24、: 失败 , 返回 EOF(-1) , 表示到达文件尾或发生错误 注 :getc,putc 是宏 4. #include FILE *stream; Int c,retval ; retval = ungetc( c,stream); retval :失败,返回EOF,如果要把EOF插回流中,肯定会失败 补充:1.c必须是用getc从缓冲区中读的一个字符(其中EOF是不能被getc读出 的,所以把 EOF 插回流中 ,必定会失败 ) 2. ungetc主要用于getc多读一个字符后,把该字符回退到缓冲区中 5. #include getchar( ) = getc( stdin ) ; put

25、char(c) = putc( c ,stdout ) .输出到 stderr 的字符是不经过缓冲区的,但 stdin,stdout 是需要经过缓冲区 6. #include int retval,fd; FILE *stream ; retval = ferror( stream ) retval = feof( stream ) clearerr(stream) fd=fileno(stream) ferror : 如果前面的输入输出发生错误,则 ferror 返回一个非零值 ;返回 0,表示没 有出错 feof :当在stream中已达到文件末时,返回非0;返回0,则表示没有达到文件末

26、clearerr: 它把 stream 的错误标志和文件末指示清为 0 .它能保证将来对这个流 的ferror和feof调用,在未发生异常情况返回时返回0值 fileno : 返回 stream 所指 FILE 结构中的文件描述符 ,但不能用 fileno 把对文件的 系统调用和标准 I/O 例行程序混合使用 7. #include char *buf , *retstring; FILE *inf ; int nsize ; retstring=gets(buf) retstring=fgets(buf,nsize,inf) gets :从标准输入流stdin中读取一个字符行,并把它放入bu

27、f指向的缓冲区 中.gets读出字符至换行符或文件末止,然后把换行符丢掉,把null(0)符 加入缓冲区中,形成一个以null符结尾的字符串.如果gets调用成功,它 返回一个指向 buf 的指针 ;如果出错或到达文件末,则返回 NULL fgets : 从流 inf 中读出字符 ,直到读出 nsize-1 的字符止 ,如果在此前遇到换行符 或文件结束.读出的字符存到缓冲区buf中.fgets不会丢弃换行符,换行符 仍被放到缓冲区.fgets成功,返回一个指向buf的指针,否则返回NULL 8. #include char *string; FILE *outf; int retval ; r

28、etval=puts(string); retval=fputs(string,outf); puts : 把 string 写到 stdout 中,但末尾的 null 字符不包括在内 ,puts 在写入部分 末尾加上一个换行符 ,但 fputs 没有这么做 puts,fputs : 出错均返回 EOF 9. #include char *buffer; int size,nitems,result; FILE *inf ,outf ; result = fread(buffer,size,nitems,inf) result = fwrite(buffer,size,nitems,outf)

29、 fread : 对应于从 inf 的输入流中读出 nitems 个目标数据 ,读出的字节放入字符型 数组buffer中,读出的每个目标是长度为 size的字节序列.result中的返回 值给出了成功读出的目标个数 fwrite :把buffer中的数据写到outf指出的流中,该缓冲区被认为由nitems个长度 为size字节的目标组成.result中的返回值给出了成功写入的目标个数 补充 :1.可以通过强制类型转换把结构等类型转换为字符 ,然后把结构写入文件中 其它的变量类型也可以用此方法进行读写操作 .例如 : struct elem char d_name15 int start ; i

30、nt length ; int type ; elist10 fwrite(char *)elist ,sizeof(struct elem) , 10 , stream ); 10. #include FILE *stream ; long offset,position; int direction,result; result=fseek(stream,offset,direction); rewind(stream); position=ftell(stream); fseek :同seek类似,fseek成功时,返回0,失败,返回非0 rewind : 把文件读写指针置为文件首,不返

31、回任何值 ftell : 返回流中的当前位置 ,从文件首开始的字节数(从 0开始计数 ) 11. #include FILE *oldstream , * newstream; char *type, * filename; int filedes; newstream=freopen(filename,type,oldstream) oldstream=fdopen(filedes,type); freopen :关闭oldstream标识的流,然后再打开它用作从file name输入.type确 定对新流的访问模式,它的取值与fopen中相同,如 ” r ” ,等这个例行 程序被用于重新指

32、定stdin,stdout,stderr.例如: freopen(“ new.input ” , ” r ” ,stdin); fdopen :把一个流与一个文件描述符关连起来,这个文件描述符取自前面的系 统调用 open,creat,pipe,dup 等 freopen,fdopen :如出错,均返回NULL,它门打开的文件的关闭均用fclose 12. #i nclude FILE *stream; char buf1BUFSIZ,buf2SOMEV ALUE; int type,size,res; setbuf(stream,buf1); res=setvbuf(stream,buf2,

33、type,size); setbuf :用buf1取代标准I/O库正常分配的缓冲区,buf1的长度由stdio.h中定 义的常数BUFSIZ决定.如果把一个NULL字符型指针传给setbuf,那 么就使输入和输出不在经过缓冲.在对程序调试时,常常需要这样做. setvbuf : buf2给出了一个新的缓冲区的值,size为该缓冲区的长度.如果用NULL 来做buf2之值,就标示用系统默认的缓冲区.type为确定stream被缓 冲的方法,可以用它来调整流,使之更适合磁盘文件和终端设备的使 用type的取值如下: OFBF:流完全被缓冲,这是不与终端关联的默认方式.所以,以 BUFSIZ个字节为

34、单位来读写数据,可获得最高效率 OLBF:输出以行被缓冲,只要写入换行符 緩冲区就被冲刷清. 当缓冲区满时,或请求输入时,缓冲区也将被刷清.这是 终端的默认方式,它适合交互使用. OBNF:这导致输入输出都不被缓冲,在这种情况下,buf2和 size均被忽略 如果type或size的值为非法值,那么setvbuf就返回一个非0值;成功, 就返回0 3.1进程控制 .fork中父子进程间的关系图: 从上图可看出 ,父子进程共享同一个程序段 ,但各自拥有自己的堆栈 ,数据段 ,用 户空间及进程控制块 .当核心程序收到 fork( )需求时 ,操作系统会给子进程一个进 程标识符 ,并且设定 CPU

35、时间,设定与父进程共享的区段 ,同时将父进程的 I 节点 拷贝一份到子进程的用户区域里 ,然后子进程的数据段与堆栈会被重新指定一份 给子进程使用 ,最终子进程会返回数值 0,以标识它是子进程 . .exec 系统调用后 ,新进程将代替老进程 ,原进程的堆栈 ,数据段与程序段都会被修 改,只有用户区和进程标识维持不变. 1. fork, 文件 ,数据 首先 ,用 fork 生成的子进程的所有变量均是父进程的变量的值的拷贝;其次 ,在 父进程中打开的文件 ,在子进程中也被打开 .但是 ,被打开的文件的文件指针是由系 统保存的 ,在系统中仅有一份拷贝 ,当在子进程中移动文件指针时 ,也等于移动了父

36、进程的文件指针 .在父进程中移动文件指针时 , 也等于移动了子进程的文件子针 2. exec 和打开文件 当调用exec时,在原进程中打开的文件,在新进程中也被打开但通过fcntl()函 数设置文件的执行关闭位,可在exec调用时,关闭打开的文件(但保留stdin, stdout,stderr 的打开 ),对”执行关闭 ”位 的操作如下 : #include int fd ; fd=open( “ file ” ,O_RDYO);NL 设置 : fcntl(fd,F_SETFD,1); 关闭 ,并取得返回值 : res=fcntl(fd,F_GETFD,0); 其中如果文件描述符 fd对应的文

37、件的”执行关闭”位被设置则res之值为1, 否则res之值为0 3. exec和fork的联用 进程首先调用fork()生育一个子进程,然后在子进程中调用 exec再生育一个 进程 ,这样就实现了父进程运行一个与其不同的子进程,并且父进程不会被覆盖 4. 进程终止的特殊情况 子进程终止时 ,父进程并不正在执行 wait 调用 当子进程尚未终止时 ,父进程却终止 在第一种情况 ,有终止的进程处于一种过度状态,处于这种状态的进程不使用 任何内核资源 ,但要占用内核进程中的进程处理标内的一项.当其父进程执行 wait 等待子进程时 ,它会进入睡眠状态 .然后把这种处于过渡状态的进程从系统内删除, 父

38、进程仍将能得到该子进程的结束状态 . 在第二种情况中 ,一般允许父进程结束 ,并把它的子进程 (包括处于过渡状态的 进程 )交归系统初始化进程所属 . 3.2 进程控制的系统调用 1.int pid ; pid = fork( ) pid : 在父进程中 :成功 ,pid 为子进程的的进程标识符 失败 ,pid 为一负数 在子进程中 :成功 ,pid 为 0 失败 ,pid 为一负数 2.int execl(path,argO,arg1,,argn,(char *)0) int execv(path,argv) int execle(path,arg0,arg1,argn,(char *)0,

39、envp) int execve(path,argv,envp) int execlp(file,arg0,arg1,.,argn,(char *)0) int execvp(file,argv) char *path,*arg0,*arg1, ,*argn; char *file, *argv,envp; path : 指向被执行程序的完整路径名 , 例如 : /bin/ls file : 指向被执行的程序的文件名 ,例如: ls arg0,.,argn : 是一组要传给新进程的参数,它门的数据类型是字符串 argv , envp : 同 main( ) 函数的 argv 和 envp, 此

40、时 envp 为新进程的新环境 ; exec 执行失败的返回值为 -1 补充:1.可以通过main()函数的argc,argv变量来访问execl传给它们的参数 2. execl 与 execlp 的主要区别是 :execlp 的第一个参数是一个简单的文件名 , 而不是一个路径名 .它们通过检索 SHELL 环境变量的 PATH 指出的目录 来得到该文件的路径前缀部分 . 3. int status ; exit(status); status : 0到 255,其中 0 表示程序的正常终止 ,1 到 255 则指程序因错误而终止 功能 :1.终止进程 ,关闭所有打开的文件 2. 完成一些系统

41、内部的清理工作,如缓冲区的清除 3. 当父进程因执行 wait 而睡眠时 ,子进程执行 exit 会重新启动父进程 ,同 时,父进程能使用exit的参数status的低8位 4.int retval,status retval=wait( 子进程被另一个进程用一种称为信号的通信机构停止,而不是通过 exit() retval : 成功 ,结束进程的标识符 : 子进程正常结束或调用exit结束status的低8位0,第8位到第15 为子进程 exit(status)的退出码 status 子进程被另一个进程用一种称为信号的通信机构停止,此时 status 的低 8 位不为 0,8到 15位为终止

42、此进程的信号 失败, 返回 -1,表示没有子进程结束 ,errno 的值为 ECHILD 4.1 信号处理 1. 中 断与自陷的区别 : 中断 :外部设备和中央处理机并行工作时 ,若外部设备完成了某一预定的输 入 ,输出 (I/O) 操作 ,它就要求处理机暂停正在执行的程序 , 转而对它进行 必要的处理 (例如 ,检查在 I/O 过程中是否发生过某种错误 ,如若出错则 进行出错处理 ;如未出错则通知与该 I/O 有关地进程 ,然后启动外设执 行下一个 I/O 请求 ),这种显现称为中断 . 中断的类型 : I/O 中断 外部设备完成预定的 I/O 操作或执行 I/O 操作时出错 进管中断 执行

43、进入系统调用的指令时引起的中断 断点跟踪中断 为了调试程序 ,有些系统设置了断点指令以及断点状态 位等 ,使得程序在运行中达到了某些预定点后能自动停 止下来 ,并有中断方式通知系统 ,这种中断称为断点跟踪 中断 硬件故障中断 它是机器故障或由机器故障造成出错时产生的中断 程序性中断 由程序中的错误引起的中断 ,如使用非法指令 ,浮点运算出 错,地址越界 其中称为中断,称为自陷 陷入处理 : 等待系统管理员干预如陷入前为核心态 ,则除浮点溢出外 ,皆为故障 , 用户态下的电源失效也属于此类 .对于这些故障 ,系统 只有进入死循环等待系统操作人员干预 按用户规定方式进行处理在用户态下发生的陷入 ,

44、除电源失效 ,系统调 用,段违例外 ,皆按陷入类型转换为信号 .然后将信号送 入现运行近程的 p-sig 用户栈自动扩充 在发生段违例时 ,首先是力图恢复造成段违例的指令 执行前的现场 .如成功 ,则检查用户栈是否溢出 .若溢出 则扩充用户栈 .如扩充成功 ,则处理结束 ;否则将信号 SIGSEG 送 p-sig 并按第二种方式处理 . 系统调用处理 如陷入前为用户态 ,则进入系统调用 2. 信号与信号机构 .信号的产生见上 ; .信号 .信号机构指的是系统中围绕信号的产生,传送和处理而构成的一套机制 处理机制除故障和特殊陷入指令处理外 ,还处理以下两种情况 : 用户使用键盘上的特定功能键对相

45、关进程进行控制 用户态进程之间以传送信号方式进行简单通信 3. 信 号类型 (略 ) 4. 信号的产生 ,传送和同步 信号的产生 : 在陷入处理子程序中 ,针对用户态下产生的各种故障以及使 用的各种陷入指令产生不同类型的信号 .然后将此信号送入 该进程 proc 中的 p-sig 项 . 进程之间传送信号 .进程之间通过系统调用 kill 进行信号传 送. 用户在终端机键盘上击特定功能键” DELETE和” QUIT”终 端机输入中断处理子程序将信号 SIGINT 或 SIGQIT 送入与 该终端相关的所有进程 进程将信息写入通讯文件 pipe 时 ,发现该文件读通道已经关 闭 ,也就是没有一

46、个进程从中读取信息,则向本进程发送 SIGPIPE 信号 父进程对接到一个信号子进程进行跟踪处理时,可用跟踪命 令向子进程传送一信号 上述五种情况除最后一种外 ,都使用 psignal 程序实施信号传送 . 信号的传送 psignal(int p,const char *sig) 将信号 sig 送到 p 指向的进程的 proc 中的 p-sig 项.一个进程只有一个 p-sig 项 ,它在任何时候只能记住接到的一个信 号 .如果进程对上一次接到的信号处理尚未结束时,又接到另一个信号 ,则一 般后一个信号将取代前一个信号(无论同种还是不同种信号 ).但 SIGKIL 信 号例外 ,它不被后来的

47、信号取代 .若接到信号的进程的优先数大于 PUSER(IOO),则将其置为PUSER;若该进程处于低优先全睡眠状态,则立即 将其唤醒 . 信号的同步 进程用 kill 向另一进程传送信号时 ,为了保持进程间的同步 ,接收进程 调用sleep或pause系统调用,使接收进程处理低优先权睡眠状态 当发送 进程发送信号时 ,会将处于低优先权睡眠状态的接收进程唤醒 5. 信号的处理方式 ,进程接收到信号后的处理方式有三种 : 终止进程 ,这是针对用户态下故障信号最常用的一种方法 忽略该信号 ,不做任何处理 执行预先编写好的位于虚地址空间的信号处理程序 ,这种处理方式通过调 用系统调用 signal(s

48、ig,func) 来设定 .但 SIGKIl 信号不能用此方法来设定 , 其缺省方式是为终止接收到该信号的进程 注:进程对信号的处理方式记录在信号处理表u-signalNSIG 中,相应元素值 为 0,采用第一种处理方式 ;为奇数 , 采用第二种处理方式 ;为偶数 , 采用第 三种处理方式 4.2 信号系统调用 1. #include void abort () 功能 :向调用进程发送一个信号,产生一个非正常终止 ,导致 coredump 2. #include int func( ), (* was)( ) , sig ; was = signal( sig,func ); sig : 可以为信号系统中除 SIGKIL 和 SIGSTOP 外的任何信号 func : 为一返回值为整型 ,入口参数为 sig 的函数 was : 成功 ,为一指向信号原来相关连的函数的函数指针 失败,传送非法信号或明或SIGKIL,返回值为(int(*)( )-1,同时置errno为 EINV AL,意思是无效参数 SIG_IGN :表示忽略信号,其定义为 #define SIGGN(int(*()1 SIG_DEL:表示恢复系统对信号的默认工作定义#define SIG_DFL (int(*()0 SIG_HOLD:暂时搁置该信号,其定义为 #de

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论