欢迎来到得力文库 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
得力文库 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    UNIX编程初步.pdf

    • 资源ID:70321836       资源大小:581.06KB        全文页数:51页
    • 资源格式: PDF        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    UNIX编程初步.pdf

    UNIX 编程初步黄永峰清华大学电子工程系网络与人机通信研究所:62785717Email:RFYTSINGHUA.EDU.CNUNIX的体系结构硬件内核Kernelshwhoa.outdatewcgrepedvildcompcpp其他 应用程序CC图1 UNIX 体系结构UNIX 的基本特点?是一种多任务、多用户、可移植性、层次性文件系统的分时OS?核心程序?命令解释器Shell?安全性?文件系统?网络功能UNIX的多任务、多用户实现?多任务和分时?进程、进程环境、进程状态。?PID0-fork()-PID1?核心态、用户态、睡眠态、就绪态。?进程转态的转换。?进程的保护:特权系统(4个级别)。?用户使用UNIX的4个层次。?系统调用System Call。1243用户态 核心态睡眠态 就绪 态System CallReturn图2 进程状态及其转换UNIX的Kernel?常驻内存的数据和程序,同硬件直接打交道,为应用程序服务。?Kernel是可根据用户需求和硬件环境裁剪。?主要功能:I/O管理、硬件管理、进程调度、内存管理和文件管理等。?SCO UNIX的Kernel在/unix文件。Shell?提供用户访问UNIX的Kernel的接口,是一种交互式命令解释器,也是一种命令级程序设计语言。?Shell的版本:B Shell、C Shell、K Shell和V Shell等。?B Shell标准Shell,又称为Bourne shell。?Shell执行命令的过程:接收命令-建立子Shell-执行-子进程结束。文件系统的特点?层次的树型结构。?能建立和删除文件。?文件可动态增长。?文件数据的保护。?外设也作为文件。(root)bindevunixetcbootlib.tty00tty10h.chomebininclude图3 SCO UNIX的目录树default安全机制?用户注册。?用户等级(文件主、同组用户、其他用户)。?文件访问权限(读r,写w,执行x)。例如:ls-l ux01-rwxr-xr-jinning other Dec 18:09 1997 ux01?文件和目录的权限和属组可以修改。例如:chmod(change modify)、chgrp(change group)。网络功能?NOS 的三足鼎立:NetWare、Windows NT、UNIX。?UNIX是Internet的根基。?UNIX的通信协议:TCP/IP、UUCP。?UNIX的联网方式:LAN和Modem。?网络功能:Telnet,FTP、WWW、e-mail等。UNIX的标准和实现?UNIX的三大标准:ANSI指定了C语音的规格说明。IEEE POSIX 是IEEE指定的标准簇(Portable operation system interface for computer environment),具体文件是1003.1。X/Open XP G3,X/OPEN 是一个国际计算机制造商组织,XGP3是它提供的X/Open Portable Guiding Ver.3.?UNIX的各种版本和变体都是起源于PDP-11系统上运行的UNIX 分时系统的V6和V7.在此基础上有三个分支:A&T的UNIX实验室导出了商业版本,即SVR4,符合POSIX 1003.1标准和X/Open XPG3标准.第二分支是加州伯克利分校的4.XBSD.第三分支是A&T的计算研究中心的研究版本.1.系统调用和C库函数(1)?所有操作系统都提供多种服务的入口点,由此向系统内核请求服务,这些入口点被称之为系统调用(system call)。?系统调用(system call)是UNIX内核与应用程序之间的唯一接口。?内核对外提供的所有的功能均以系统调用的方式出现,应用程序只有只有通过系统调用才能申请和访问硬件资源(内存和磁盘,I/O设备),如:malloc(),fork(),open(),read(),write(),close(),ioctl()。?系统调用还可以访问内核数据,如:getpid(),chdir(),umask(),等。1 系统调用和C库函数(2)?每条系统调用在标准C库中设置一个具有同样名字的函数。用户进程用标准C调用序列来调用这些函数,从应用角度可将系统调用视作为C函数。C程序员在使用系统调用和使用其它函数调用时,用法上没什么区别。?进程调用一次系统调用要导致CPU在用户态和核心态之间作一次切换,它比在进程自己的地址空间中调用一个简单的子例程要花费更长时间(所以UNIX中提供了文件缓冲I/0库程序)。1 系统调用和C库函数(3)C库函数应用代码系统调用用户进程内核2 系统调用出错处理?系统调用都返回一个整数值,如:open(),wrire(),read()等,当系统调 用的返回值为-1时,表示系统调用执行失败。?整数errno说明失败的原因。还有一个sys_errlist表,是错误代码对应的错误信息表。?系统调用失败,系统会自动地填好变量errno的值。errno可能的取值在文件中定义了宏,如:EBADF,EINTR,ENOMSG等等。?与系统调用失败有关的重要的函数是perror(),语法为perror(char*s);它会在stderr上。先印出字符串s,再印出一个冒号和空格,然后再印出这条消息和换行符。例题1#include extern int errno;extern char*sys_errlist;main()int fd;char fname100;printf(Input file name:);scanf(%s,fname);fd=open(fname,O_RDWR);if(fd=-1)printf(errno=%dn,errno);printf(”errmsg=%sn”,sys_errlisterrno);perror(Open file);else printf(OKn);/*do something here*/3 编译编译?是用vi编辑好C源程序后,再用cc命令进行编译。?五个阶段:既预处理阶段、编译阶段、优化阶段、汇编阶段和连接阶段。?cc命令的选项很多,-c:生成目标文件,但不进行连接。用于对C源文件的分别编译。-o filename,指定连接程序最后生成的可执行文件名为filename。?例:下面的命令编译ex.c并生成一个可执行文件ex:cc o ex ex.c4 文件文件I/O函数(函数(1)?I/O只要用5个函数:open、read、write、lseet以及close。?对于系统内核而言,所有打开的文件都由文件描述符引用。一个文件描述符是个非负整数。文件描述符的范围是0-OPEN_MAX。/usr/include/limits.h文件中找到OPEN_MAX的定义。?按照惯例,Unix Shell使文件描述符0与一个进程的标准输入相结合,使文件描述符1与标准输出相结合,使文件描述符2与标准出错输出相结合。4 文件文件I/O函数(函数(2)系统调用open使文件描述符与文件或物理设备相关联。#include#include#include int open(const char*pathname,int oflag,/*mode_t mode*/);O_RDONLY 只读打开,O_WRONLY 只写打,O_RDWR 读、写打开。O_APPEND-在每次写时都加到文件的尾端。O_CREAT-若此文件不存在则创建它。如果oflag字段设置了O_CREAT,它应该包含第三个参数。第三个参数的类型为mode_t(unsigned short16bit),指 定 文 件 的 权 限 为 一 个 mode_t 值(rwxrwxrwx)例如fd=open(“/usr/no1/my.dat”,O_CREAT,0644)=-1)4 文件文件I/O函数(函数(3)用close函数关闭一个打开文件:#include int close(int filedes);返回:若成功为0,出错为-14 文件文件I/O函数(函数(4)?lseek函数:每个打开文件都有一个与其相关联的“当前文件位移量”。?off_t lseek(int filedes,off_t offset,int whence);返回:若成功为新的文件位移,出错为-1。?若whence是SEEK_SET,则将该文件的位移量设置为距文件开始处offset个字节。若whence是SEEK_CUR,则将该文件的位移量设置为其当前值加offset。offset 可为正或负。whence是SEEK_END,则将该文件的位移量设置为文件长度加offset,offset可为正或负。?例如:off_t currpos;currpos=lseek(fd,0,SEEK_CUR);4 文件文件I/O函数(函数(5)read:从打开文件中读数据。ssize_t read(int filedes,void*buff,size_t nbytes)如read成功则返回读到的字节数。如果已到达文件的尾端,则返回0。读操作从文件的当前位移量处开始,在成功返回之前,该位移量增加实际读得的字节数。Write:用函数向打开文件写数据。ssize_t write(int filedes,const void*buff,size_t nbytes);返回:若成功为已写的字节数,出错为-1写操作从文件的当前位移量处开始。如果在打开该文件时,指定了O_APPEND选择项,则在每次写操作之前,将文件位移量设置在文件的当前结尾处,在一次成功写之后,该文件位移量增加实际写的字节数5 文件和目录操作文件和目录操作(1)?stat、fstat 和lstat 函数?#include?#include?int stat(const char*p a t h n a m e,struct stat*b u f);?int fstat(int f i l e d e s,struct stat*b u f);?int lstat(const char*p a t h n a m e,struct stat*b u f);?给定一个pathname,t函数返回一个与此命名文件有关的信息结构5 文件和目录操作文件和目录操作(2)?struct stat?mode_tst_mode;/*文件类型和方式(许可数)*/?ino_tst_ino;/*i-节点号(序列号)*/?dev_tst_dev;/*设备号(文件系统)*/?dev_tst_rdev;/*特殊文件的设备号*/?nlink_tst_nlink;/*连接数*/?uid_tst_uid;/*属主的用户ID*/?gid_tst_gig;/*属主的组ID*/?off_tst_size;/*普通文件的字节长度*/?time_tst_atime;/*最后存取时间*/?time_tst_mtime;/*最后修改存取时间*/?time_tst_ctime;/*最后文件状态更改时间*/?longst_blksize;/*最佳I/O块长*/?longst_blocks;/*分配的512字节块块数*/?;stat函数的最大用户很可能是ls-l命令,用其可以获得文件的所有信息5 文件和目录操作文件和目录操作(3)?普通文件(regular file)。最常见的文件类型,包含了某种形式的数据。至于这种数据是文本还是二进制数据对于内核而言并无区别。对普通文件内容的解释由处理该文件的应用程序进行。?目录文件(directory file)。包含了其他文件的名字以及指向与这些文件有关信息的指针。对一个目录文件具有读许可权的任一进程都可以读该目录的内容,但只有内核可以写目录文件。?字符特殊文件(character special file)。用于系统中某些类型的设备。?块特殊文件(block special file)。用于磁盘设备。系统中的所有设备或者是字符特殊文件,或者是块特殊文件。?F I F O。用于进程间的通信,有时也将其称为命名管道。?套接口(s o c k e t)。用于进程间的网络通信。套接口也可用于在一台宿主机上的进程之间的非网络通信。?符号连接(symbolic link)。这种文件指向另一个文件5 文件和目录操作文件和目录操作(4)文件类型信息包含在stat结构的st_mode成员中。可以用下表中的宏确定文件类型。宏的参数都是stat.st_mode成员。宏文件类型S_ISREG()普通文件S_ISDIR()目录文件S_ISBLK()字符特殊文件S_ISBLK()块特殊文件S_ISFIFO()管道或FIFOS_ISLNK()符号连接(SVR4中无此类型)S_ISSOCK()套接字(SVR4中无此类型)文件和目录操作文件和目录操作(5)#include?#include?int main(int argc,char*argv)?int i;struct stat buf;char*ptr;?for(i=1;iargc;i+)?printf(%s:,argvi);?if(lstat(argvi,&buf)0)?printf(lstat error!n);?continue;?if(S_ISREG(buf.st_mode)ptr=regular;?else if(S_ISDIR(buf.st_mode)ptr=directory;?else if(S_ISCHR(buf.st_mode)ptr=character special;?else if(S_ISBLK(buf.st_mode)ptr=block special;?else if(S_ISFIFO(buf.st_mode)ptr=fifo;?else ptr=unkonwn mode 0;?printf(%sn,ptr);?exit(0);设置-用户-I D 和设置-组-I D?实际用户I D 和实际组I D 标识我们究竟是谁。在登录时取自口令文件中的登录项。?有效用户I D,有效组I D 以及添加组I D 决定了文件访问权.?保存的设置-用户-I D 和设置-组-I D 在执行一个程序时包含了有效用户I D 和有效组I D 副本.?每个文件有一个所有者和组所有者,所有者由s t a t 结构中的s t _ u i d 表示,组所有者则由s t _ g i d 成员表示。?当执行一个程序文件时,进程的有效用户I D 通常就是实际用户I D,有效组I D 通常是实际组I D.?设置-用户-I D(s e t-u s e r-I D)位和设置-组-I D(s e t-g r o u p-I D)位:可以在文件方式字(s t _ m o d e)中设置一个特殊标志,其定义是“当执行此文件时,将进程的有效用户I D 设置为文件的所有者(s t _ u i d).?例如:若文件所有者是超级用户,而且设置了该文件的设置-用户-I D 位,当该程序由一个进程运行时,则该进程具有超级用户优先权。不管执行此文件的进程的实际用户I D 是什么.文件和目录操作文件和目录操作(7)Chmod和和chown函数函数:可以更改文件的存取许可权。?#include?#include?int chmod(const char*pathname,mode_t mode);?int fchmod(int filedes,mode_t mode);?二个函数返回:若成功为0,出错为-1.?为了改变一个文件的许可权位,进程的有效用户ID必须等于文件的属主,或者该进程必须具有超级用户许可权。?例:set absolute mode to“rw-rr“?chmod(“myfile”,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);?chown函数可用于更改文件的用户ID和组ID?int chown(const char*pathname,uid_t owner,gid_t group);?int fchown(int filedes,uid_t owner,gid_t group);文件和目录操作文件和目录操作(8)Mode 说明S_IRWXU用户读、写、执行S_IRUSR用户读S_IWUSR用户写S_IXUSR用户执行S_IRWXG组读、写、执行S_IRGRP组读S_IWGRP组写S_IXGRP组执行S_IRWXO其他读、写、执行S_IROTH其他读S_IWOTH其他写S_IXOTH其他执行文件和目录操作文件和目录操作(8)1.用mkdir函数创建目录。#include#includeint mkdir(const char*pathname,mode_t mode);2.用rmdir函数可以删除一个空目录#includeint rmdir(const char*pathname);3.chdir函数可以更改当前工作目录int chdir(const char*pathname);4.DIR*opendir(const char*pathname);5.void rewinddir(DIR*dp);6.int closedir(DIR*dp);6.系统数据文件与信息系统数据文件与信息(1)-口令文件口令文件说明struct passwd 成员用户名Char*pw_name加密口令Char*pw_passwd用户IDUid_t pw_uid组IDGid_t pw_gid注释字段Char*pw_gecos初始工作目录Char*pw_dir初始shellChar*pw_shell6.系统数据文件与信息系统数据文件与信息(2)-口令文件口令文件?口令字文件是/etc/passwd,而且是一个文本文件。每一行包 含 7 个 字 段,字 段 之 间 用 冒 号 相 分 隔。例如:root:jheVopR58x9Fx:0:1:The superuser:/:/bin/sh?nobody:*:65534:65534:/:?通常有一个记录项,其用户名为root。此记录项的用户ID是0(超级用户)。?密码口令字字段包含了经单向密码单法处理过的用户口令字副本。当前使用的算法总是产生13个可打印字符。?在口令字文件记录中的某些字段可能是空。如果密码口令字段为空,这通常就意味着该用户没有口令字。6.系统数据文件与信息系统数据文件与信息(3)-口令文件口令文件1.查看相关记录。#include include struct passwd*getpwuid(uid_t uid);struct passwd*getpwnaw(const char*name);2.查看整个口令字文件#include#include struct passwd*getpwent(void);void setpwent(void);void endpwent(void);6.系统数据文件与信息系统数据文件与信息(4)-系统时间和日期系统时间和日期1、Unix系统核提供的基本时间国际标准时公元1970年1月1日 00:00:00以来经过的秒数。以数据类型time-t(32bit)表示的,称之为日历时间。2、time函数返回当前时间和日期。#include time_t time(time_t*calptr);3、函数localtime和gmtime将日历时间(time_t)变换成以年、月、日、时、分、秒表示的时间,将这些存放在一个tm结构中。区别是:localtime将日历时间变换成本地时间(考虑到本地时区和夏日制标志),而gmtime则将日历时间变换成国际标准时的年、月、日、时、分、秒、周日。4、函数mktime以本地时间的年、月、日等作为参数,将其变换成time-t值。6.系统数据文件与信息系统数据文件与信息(5)-系统时间和日期系统时间和日期struct tm /*a broken-down time*/以年、月、日、时、分、秒表示的时间int tm_sec;/*seconds after the minute:0,61*/秒int tm_min;/*minutes after the hour:0,59*/分int tm_hour;/*hours after midnight:0,23*/时int tm_day;/*day of the month:1,31*/日int tm_mon;/*month of the year:0,11*/月int tm_year;/*years since 1900*/1900后的年int tm_wday;/*days since Sunday:0,6*/星期几int tm_yday;/*days since January 1:0,365*/自1月1日经过的天数,int tm_isdst;/*daylight saving time flag:0*/夏日制时间标志:0;7 UNIX进程控制(1)?每个进程都有一个非负整型的唯一进程ID。因为进程ID标识符总是唯一的,常将其用作为其它标识符的一部分以保证其唯一性。?专用的进程:进程ID0是调度进程,又称为交换进程(swapper)。该进程并不执行任何磁盘上的程序-它是系统核的一部分,因此也被称为系统进程。进程ID1通常是init进程,在自举过程结束时由系统核调用。该进程的程序文件是/sbin/init。此进程负责在系统核自举后起动一个Unix系统。?除了进程ID,每个进程还有一些其它标识符。7、UNIX进程控制(2)-fork函数?现存进程调用fork函数是Unix核创建一个新进程的唯一方法。?fork执行返回后,两个进程(父和子)都收到返回值,但不相同。用于区分父进程(返回值0,是子进程的PID)和子进程(返回值=0。?内核在实现fork调用时,首先初始化创建一个新的proc结构,然后复制父进程环境(包括user结构和内存资源)给子进程。?pid_t fork(void);返回:子进程中为0,父进程中为子进程ID,出错为0 7、UNIX进程控制(3)-举例?#include?intglob=6;/*external variable in initialized data*/?Char buf=a write to stdoutn;?int main(void)?intvar;/*automatic variable on the stack*/?pid_tpid;var=88;?printf(before forkn);/*we dont flush stdout*/?if(pid=fork()0)printf(fork error);?exit(1);?else if(pid=0)/*child*/?glob+;var+;?else?sleep(2);/*parent*/?printf(pid=%d,glob=%d,var=%dn,getpid(),glob,var);?exit(0);8 信号-定义?信号是软件中断,每个信号都有一个名字。以三个字符S I G 开头。例如,S I G A B RT.?产生一个信号的条件:?当用户按某些终端键时,产生信号。在终端上按D E L E T E 键通常产生中断信号(S I G I N T)。?硬件异常产生信号:除数为0、无效的存储访问等等。这些条件通常由硬件检测到,并将其通知内核。然后内核为该条件发生时正在运行的进程产生适当的信号。?进程用k i l l(2)函数可将信号发送给另一个进程或进程组。但要求接收信号进程和发送信号进程的所有者必须相同,或发送信号进程的所有者必须是超级用户。?用户可用k i l l(1)命令将信号发送给其他进程。此程序是k i l l 函数的界面。常用此命令终止一个失控的后台进程。?当检测到某种软件条件已经发生,并将其通知有关进程时也产生信号。这里并不是指硬件产生条件(如被0 除),而是软件条件。例如S I G A L R M(进程所设置的闹钟时间已经超时)。8 信号-信号处理?忽略此信号。大多数信号都可使用这种方式进行处理,但有两种信号却决不能被忽略。它们是:S I G K I L L 和S I G S TO P。这两种信号不能被忽略的原因是:它们向超级用户提供一种使进程终止或停止的可靠方法。?捕捉信号。内核在某种信号发生时,调用一个用户函数。在用户函数中,可执行用户希望对这种事件进行的处理。例如:如果捕捉到S I G C H L D 信号,则表示子进程已经终止,所以此信号的捕捉函数可以调用w a i t p i d以取得该子进程的进程I D 以及它的终止状态。又例如,如果进程创建了临时文件,那么可能要为S I G T E R M 信号编写一个信号捕捉函数以清除临时文件(k i l l 命令传送的系统默认信号是终止信号)。?执行系统默认动作。系统默认动作是终止该进程。8 信号-类型?SIGABRT:调用abort函数时产生此信号。?SIGALRM:超过alarm和setitimer(2)函数设置的时间时产生此信号。?SIGCHLD:在一个进程终止或停止时,SIGCHLD信号被送给其父进程。调用wait函数可取得子进程ID和其终止状态。?SIGINT:当用户按中断键(常常是DELETE或Control-C)时,终端驱动程序产生此信号并送至前台进程组中的每一个进程?SIGKILL:向系统管理员提供了一种可以消灭任一进程方法?SIGPIPE:如果在读进程已终止时写管道,则产生信号SIGPIPE。当套接口的一端已经终止时,一个进程写该插口也产生此信号。?SIGQUIT:当用户在终端上按退出键(常常是Control-)时,产生此信号。?SIGSTOP:这是一个作业控制信号,它停止一个进程。?SIGSYS:这指示一个无效的系统调用。?SIGTERM:这是由kill(1)命令发送的系统默认终止信号。?SIGTRAP:硬件故障。此信号名来自于PPP-11的TRAP指令。?SIGUSR1:是一个用户定义的信号,可用于应用程序。?SIGUSR2:是一个用户定义的信号,可用于应用程序。8 信号-signal函数?#include?void(*signal(int signo,void(*func)(int)(int);?返回:signal的返回值则是指向以前的信号处理程序的指针。错时SIG-ERR?signal参数是信号名。func的值是(a)常数SIG-IGN,或(b)常数SIG-DFL,或(c)当接到此信号后要调用的函数的地址。如果指定SIG-IGN,则向系统核表示要忽略此信号。(要记住有两个信号SIGKILL和SIGSTOP是不能忽略的。)如果指定SIG-DFL,则表示接到此信号后的动作是系统默认动作。当指定函数地址后,称此为捕捉此信号。称此函数为信号处理程序或信号一捕捉函数。8 信号-举例?#include?static voidsig_usr(int);/*one handler for both signals*/?int main(void)?if(signal(SIGUSR1,sig_usr)=SIG_ERR)?printf(cant catch SIGUSR1);exit(1);?if(signal(SIGUSR2,sig_usr)=SIG_ERR)?printf(cant catch SIGUSR2);exit(1);?for(;)pause();?static void sig_usr(int signo)/*argument is signal number*/?if(signo=SIGUSR1)?printf(received SIGUSR1n);?else if(signo=SIGUSR2)?printf(received SIGUSR2n);?else printf(received signal%dn,signo);exit(1);?return;?8 信号信号-kill和和raise函数函数?Kill函数将一个信号发送给一个进程或一个进程组。raise函数则允许一个进程向自身发送一个信号。?#include?#include?int kill(pid_t pid,int signo);?int raise(int signo);?id0 将信号发送给进程ID为pid的进程。?pid=0 将信号发送给其进程组、而且发送进程有许可权向其发送信号的所有进程。?pid0 将信号发送给其进程组ID等于pid绝对值、而且发送进程有许可权向其发送信号的所有进程。?每个进程在其proc结构中都记录了p_pid,p_ppid和p_pgrp三个PID号,p_pid是进程自己的PID,p_ppid是父进程的PID,p_pgrp都相同的进程构成一个“进程组”,如果p_pgrp=p_pid则该进程是组长。8 信号信号-alarm和和pause函数函数?使用alarm函数可以设置一个时间值(闹钟时间),在将来的某个时刻该时间值会被超过。当所设置的时间值被超过后,产生SIGALRM信号。?#includeunsigned int alarm(unsigned int seconds);返回:0或以前设置的闹钟时间的余留秒数。注意:每个进程只能有一个闹钟时间。如果在调用alarm时,以前已为该进程设置过闹钟时间,而且它还没有超时,则该闹钟时间的余留值作为本次alarm函数调用的值返回。以前登记的闹钟时间则被新值代换。?pause函数使调用进程挂起直至捕捉到一个信号。#includeint pause(void);9.信号灯?信号灯信号灯(semaphore)是是UNIX提供的一种机制,它用于控制多个进程对共享资源的互斥性访问和进程之间的同步提供的一种机制,它用于控制多个进程对共享资源的互斥性访问和进程之间的同步.?UNIX提供的信号灯系统调用提供的信号灯系统调用#include#include#include int semget(key,nsems,flags)/*创建一个新的或获取一个已存在的信号灯组创建一个新的或获取一个已存在的信号灯组*/int key;/*信号灯组的信号灯组的KEY*/int nsems;/*该信号灯组中包含有多少个信号灯该信号灯组中包含有多少个信号灯*/int flags;/*option flags*/*函数返回一个整数函数返回一个整数,是信号灯组的是信号灯组的ID号;返回号;返回-1,表明调用失败,表明调用失败*/9.信号灯1.使用信号灯组时,程序需要首先根据KEY(功能类似于文件名)使用semget()系统调用创建一个新的或获取一个已存在的信号灯组,得到一个内部的信号灯组ID。2.如果semget()的参数flags&IPC_CREAT不为0,则在该KEY对应的信号灯组不存在的情况下,在系统中创建它,新创建的信号灯组中含有nsems个信号灯,flags的后9比特是该信号灯组的访问权限(类似于文件的访问权限)3.如果该KEY对应的信号灯组已经存在,则得到信号灯组的ID,参数nsems和flags无意义。4.flags还有一个常用的比特位是IPC_EXCL,当该比特置位时,只要KEY对应的信号灯组已存在,则semget()出错,返回值为-1。9.信号灯?int semop(sem_id,ops,nops)/*对信号灯操作,可能会导致调用进程在此睡眠对信号灯操作,可能会导致调用进程在此睡眠*/int sem_id;/*信号灯组的信号灯组的ID,应是应是semget()的返回值的返回值*/struct sembuf*ops;/*指向一个结构数组,其中的每一结构描述对信号灯组中的某一信号灯的一个操作指向一个结构数组,其中的每一结构描述对信号灯组中的某一信号灯的一个操作*/int nops;/*指出上述的指出上述的ops数组中有几个有效单元数组中有几个有效单元*/?int semctl(sem_id,snum,cmd,arg)/*对信号灯的控制操作,如:删除,查询状态对信号灯的控制操作,如:删除,查询状态*/int sem_id;/*信号灯组的信号灯组的ID,应是应是semget()的返回值的返回值*/int snum;/*信号灯在信号灯组中的编号信号灯在信号灯组中的编号*/int cmd;/*控制命令控制命令*/char*arg;/*执行这一控制命令所需要的参数存放区执行这一控制命令所需要的参数存放区*/*返回值为返回值为-1,标志操作失败;否则,表示执行成功,对返回值的解释依赖于,标志操作失败;否则,表示执行成功,对返回值的解释依赖于cmd*/9.信号灯1.semop()可以一次对多个信号灯施行操作。sem_id指定了信号灯组ID,nops指出操作的个数,sembuf结构数组ops描述了这nops个操作。每个sembuf结构描述一个信号灯操作:struct sembuf short sem_num;/*信号灯在信号灯组中的编号,*/short sem_op;/*信号灯操作*/short sem_flg;/*操作选项*/;2.sem_num指出要操作的信号灯在信号灯组中的编,sem_op 指出需要进行的信号灯操作。它是一个有符号整数,取值可以是一个正数,负数或0。P操作相当于执行sem_op=1的操作;V操作相当于执行sem_op=1的操作。3.对于每一个信号灯,在UNIX系统核心内部为其保留了一个整数值(semval),应用程序只能使用信号灯系统调用来访问在内核中的这个数据,新创建的信号灯的semval初值为0。多个进程在对信号灯的操作过程中,semval取值动态变化,在某一时刻,可能大于或等于0,负数。9.信号灯4.当sem_op0的操作改为大于或等于sem_op的绝对值后,系统修改semval的值(减去sem_op的绝对值),返回主调进程。5.当sem_op0时,对某一信号灯执行semop()操作,系统维护的信号灯的semval值加上sem_op,立即返回主调进程。6.当sem_op=0时,该操作不修改semval的值。如果semval大于等于0,则调用立即返回,否则一直等待直到semval变为0。7.sem_flg一般为0。8.在一次semop()调用中,semop()的参数可以指定对多个信号灯的操作,这些参数被传递到UNIX操作系统的内核,内核要么把传递过来的多个操作一下全部做完(可能要一直等待到所有的这几个操作都可以进行为止),要么什么都不做(可能正在等待一个个条件的成熟)。谢谢欢迎指正

    注意事项

    本文(UNIX编程初步.pdf)为本站会员(asd****56)主动上传,得力文库 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知得力文库 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于得利文库 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

    © 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

    黑龙江省互联网违法和不良信息举报
    举报电话:0468-3380021 邮箱:hgswwxb@163.com  

    收起
    展开