




已阅读5页,还剩94页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章Linux环境编程 7 1系统调用和库函数 操作系统对外提供的服务可以通过不同的方式实现 其中两种基本的服务方式 系统调用库函数 7 1 1系统调用 系统调用是操作系统内核提供的编程界面 系统调用函数从C语言程序员的角度看起来用法一样 都是调用一个函数 但是处理却不一样 系统调用的功能由操作系统的内核代码实现 通过一个软件中断 系统从用户态进入到内核态 在UNIX Linux MINIX等现代操作系统中 系统调用就是以函数调用的形式出现 且一般都遵循POSIX国际标准 7 1 2库函数 库函数不属于操作系统的内核部分 通过这些库函数 调用操作系统提供的功能 调用方式在C语言中 对系统调用和库函数的调用方式相同 7 2进程控制 7 2 1进程的基本概念7 2 2进程控制的相关系统调用 7 2 1进程的基本概念 所谓 进程 就是程序的一次执行 从内核角度看 它对应一个程序的执行流并且是一个资源 包括 内存处理器 文件等 分配的单位 7 2 2进程控制的相关系统调用 1 fork 功能 调用fork时 系统将创建一个与当前进程相同的新的进程 函数原型 includepid tfork void pid tvforf void 7 2 2进程控制的相关系统调用 说明 fork 系统调用后会有两个并发进程执行此程序的代码 通常将原有的进程称为父进程 而把新生成的进程称为子进程 子进程是父进程的一个副本 除了PID等少量属性不同 父进程和子进程都从fork 系统调用开始继续执行 7 2 2进程控制的相关系统调用 返回值 为了区分父 子进程 fork给两个进程返回不同的值 如果调用成功对于父进程 fork 返回新创建子进程的进程标识符PID 对于子进程 fork 返回0 如果调用失败fork 没有创建子进程 返回 1 include includeintmain pid tpid printf just1processnow n printf callingfork n pid fork if pid 0 printf Iamthechild n elseif pid 0 printf Iamtheparent n elseprintf forkfailed n printf programend n 7 2 2进程控制的相关系统调用 说明 由于父进程和子进程的运行无关 这两个并发进程的执行 到底哪个进程先执行 没有控制 父进程先返回或子进程先返回的情况都可能发生 这取决于各自的执行速度 include includeintmain pid tpid printf PIDbeforfork d n int getpid pid fork if pid 0 printf errorinfork elseif pid 0 printf Iamthechildprocess myprocessIDis d n getpid elseprintf Iamtheparentprocess myprocessIDis d n getpid includeintmyvar 0 intmain intpid pid fork if pid 0 printf forkfailed exit 1 elseif pid 0 printf childprocessexecuting n myvar 1 else wait printf childcomplete n myvar printf father myvar d n myvar exit 0 7 2 2进程控制的相关系统调用 说明 vfork的作用与fork基本相同 和fork调用不同的是 调用vfork对于父子进程的执行次序有所限制 调用vfork时 父进程被挂起 子进程运行至调用exit时解除这种状态 因此 总是子进程先返回 include include includeintmain pid tpid if pid vfork 0 printf forkerror n exit 1 elseif pid 0 printf Childprocessisprinting n elseprintf Parentprocessisprinting n exit 0 7 2 2进程控制的相关系统调用 2 getpid 功能 返回进程的PID 函数原型 include includepid tgetpid void pid tgetppid void include includeintmain intargc char argv intp printf 1 s BEGIN n argv 0 p fork if p 0 printf 2 parent p d n p elseif p 0 printf 3 child p d n p elseperror createnewprocess printf 4 MyPID d Parent sPID d n getpid getppid printf 5 s END n argv 0 7 2 2进程控制的相关系统调用 3 exec 重新初始化进程功能 使用一个可执行程序的副本覆盖调用进程的正文段和数据段 并去执行新的代码 通常把exec系统调用和fork连用 先由fork创建一个子进程 再利用exec系统调用 让他执行一个新程序 7 2 2进程控制的相关系统调用 exec系统调用有6种调用形式 includeintexecl constchar path constchar arg intexeclp constchar file constchar arg intexecle constchar file constchar arg char constenvp intexecv constchar path char constargv intexecvp constchar file char constargv intexecve constchar path char constargv char constenvp 7 2 2进程控制的相关系统调用 说明 exec函数族的作用是根据指定文件名找到相应的可执行文件 这里的可执行文件可以是二进制文件 也可是Linux下可执行的脚本 includeintmain intpid pid fork if pid 0 printf childprocessis d n pid elseif pid 0 execl bin ls ls l forkexec c 0 perror execlp printf Bye n 7 2 2进程控制的相关系统调用 说明 上面的例子可以改为execlp的系统调用 execlp ls ls l forkexec c 0 7 2 2进程控制的相关系统调用 4 exit功能 终止正在运行的程序 该函数将回收与进程相关的各种内核数据结构 把进程的状态置为TASK ZOMBIE 函数原型 includevoidexit intstatus 说明 参数status用来传递进程结束时的状态 一般来说 0表示没有意外的正常结束 其他数值表示进程出现了错误 非正常结束 7 2 2进程控制的相关系统调用 说明 一个进程调用了exit之后 该进程并非马上消失 而是变为僵尸状态 它还保留了PCB等资源没有释放 等待父进程调用wait 对其资源进行回收 7 2 2进程控制的相关系统调用 5 wait功能 等待当前进程的子进程终止 获取子进程终止的状态并回收僵尸子进程占用的系统资源 函数原型为 include includepid twait int status pid twaitpid pid tpid int status intoption 7 2 2进程控制的相关系统调用 说明 函数的返回值是已终止的子进程的PID号 status是子进程结束时 返回的进程终止状态信息的地址 调用形式可以简写为wait 0 不需要返回状态及进程的PID wait 常用来控制父 子进程的同步 include include include includeintmain pid tpc pr pc fork if pc 0 printf errorocurred n elseif pc 0 printf Thisischildprocesswithpidof d n getpid sleep 10 else pr wait NULL printf Icatchedachildprocesswithpidof d n pr exit 0 7 2 2进程控制的相关系统调用 说明 wait 常用来控制父 子进程的同步 当fork 调用成功后 父子进程分别进行 当父进程需要用到子进程的结果时 就调用wait 进行等待 在父进程中使用系统调用wait暂停父进程的执行 使之处于阻塞状态 进入阻塞队列 一旦子进程执行完毕 会产生一个终止状态信息 处于阻塞状态的父进程便会被系统唤醒 父进程提取子进程的终止状态信息 从而继续执行 7 2 2进程控制的相关系统调用 说明 当参数status不为NULL时 子进程的结束信息放在status中 利用这个状态字可以了解子程序结束的原因 在中定义了几个宏 WIFEXITED status 如果进程正常终止 则为真 可以用WEXITSTATUS stat 获得子进程的返回码 WIFSIGNALED status 如果进程异常终止 则为真 可以用WTERMSIG stat 获得子进程被杀的信号值 include includeintmain void pid tpid pid fork if pid 0 intstat printf ChildProcessis d n pid pid wait 7 2 2进程控制的相关系统调用 说明 当父进程在子进程之前终止 子进程称为 孤儿 所有的孤儿进程统统由1 进程回收 负责清除僵尸进程 7 3文件操作 7 3 1文件的基本概念7 3 2有关文件操作的系统调用 7 3 1文件的基本概念 通常 保存在外存中的数据都是以文件的形式保存的 文件描述符是用来描述被打开文件的索引值 通常情况下 通过文件描述符打开一个文件执行I O操作的 7 3 1文件的基本概念 文件的类型 普通文件文本文件二进制文件目录文件用户存放文件名及其相关信息的文件 是内核组织文件系统的一个基本结点 链接文件实际上是指向一个真实存在的文件的链接 设备文件Linux系统为外部设备提供标准接口 将外部设备视为一种特殊文件 用户可以像访问普通文件一样访问外部设备 7 3 1文件的基本概念 文件的类型 管道文件管道文件也是一种很特殊的文件 主要用于不同进程间的信息传递 7 3 2有关文件操作的系统调用 1 creat功能 创建文件 函数原型 include include includeintcreat constchar pathname mode tmode 参数 pathname 一个字符串指针 表示文件的绝对路径名或相对路径名 mode 创建文件的权限 7 3 2有关文件操作的系统调用 返回值 调用成功 则返回该文件的描述符 调用失败 则返回 1 7 3 2有关文件操作的系统调用 2 open功能 打开文件 函数原型 include include includeintopen constchar pathname intflags intopen constchar pathname intflags mode tmode 返回值 调用成功 则返回该文件的描述符 调用失败 则返回 1 7 3 2有关文件操作的系统调用 参数 pathname 一个字符串指针 表示文件的绝对路径名或相对路径名 mode 打开文件的权限flags 描述打开文件方式 7 3 2有关文件操作的系统调用 3 close功能 关闭文件 函数原型 includeintclose intfd 参数 fd 是需要关闭文件的描述符返回值 调用成功 返回0 调用失败 则返回 1 7 3 2有关文件操作的系统调用 4 read 读文件功能 打开文件 函数原型 include include include includesize tread intfd constvoid buf size tcount 7 3 2有关文件操作的系统调用 参数 fd 文件描述符buf 缓冲区指针count 本次读操作希望读取的字节数 返回值 调用成功 返回本次实际读取的字节数 调用失败 则返回 1 7 3 2有关文件操作的系统调用 5 write 写文件功能 打开文件 函数原型 include include include includesize twrite intfd constvoid buf size tcount 7 3 2有关文件操作的系统调用 参数 fd 文件描述符buf 缓冲区指针count 本次写操作所要写入文件的字节数 返回值 调用成功 返回实际写入的字节数 调用失败 则返回 1 include include include includeintmain intargc char argv intfd1 fd2 n charbuf 512 ch n if argc0 write fd2 buf n close fd1 close fd2 7 3 2有关文件操作的系统调用 说明 在Linux系统中 每个进程启动时都自动打开三个文件 标准输入 标准输出和标准出错文件 分别对应文件描述符0 1 2 宏定义见文件 usr include unistd h defineSTDIN FILENO0 Standardinput defineSTDOUT FILENO1 Standardoutput defineSTDERR FILENO2 Standarderroroutput include include include include include includeintmain intfd1 fd2 fd3 nbytes intflags O CREAT O TRUNC O WRONLY charbuf 10 while nbytes read fd1 buf 10 0 if write fd2 buf 10 0 perror write dev null if write fd3 buf nbytes 0 perror write tmp foo bar write STDOUT FILENO buf 10 7 3 2有关文件操作的系统调用 6 lseek功能 文件定位 函数原型 include includeoff tlseek intfd off toffset intwhence 参数 fd 文件描述符offset 偏移量whence 用于表示计算偏移值的相对位置 7 3 2有关文件操作的系统调用 whence的含义 返回值 调用成功 返回相对于文件开头的实际偏移量 调用失败 则返回 1 include include include includecharbuf1 abcdefghij charbuf2 ABCDEFGHIJ intmain void intfd if fd creat file hole 0644 0 printf createrror if write fd buf1 10 10 printf buf1writeerror if lseek fd 40 SEEK SET 1 从文件开头偏移40个字节printf lseekerror if write fd buf2 10 10 printf buf2writeerror exit 0 7 4进程通信 所谓进程通信 IPC 就是指多个进程间相互通信 交换信息的方法 本地进程间通信 管道 pipe 命名管道 namedpipe 消息队列 message 共享内存 sharedmemory 信号 signal 信号量 semaphore 远程通信 套接字 socket 7 4 1管道 1 原理在Linux系统中 管道是一种特殊的文件 它的主要用途是用来实现进程间的通信 当一个管道建立后 将获得两个文件描述符 分别用于对管道读取和写入 通常将其称为管道的写入端和管道的读取端 7 4 1管道 2 pipe系统调用功能 创建一个管道 函数原型 includeintpipe intfiledes 2 参数 filedes 2 包括2个整数的数组 存放打开文件描述符 filedes 0 存放管道读端文件描述符 filedes 1 存放管道写端文件描述符 7 4 1管道 2 pipe系统调用返回值 调用成功 返回0 调用失败 则返回 1 并将出错码存入errno变量 说明 实现两个进程通过管道进行通信的做法 在调用pipe后 调用fork函数派生一个子进程 然后 根据传输的方向 分别关闭父进程和子进程中的一个文件描述符 include include includeintmain intn fd 2 pid tpid if pipe fd 0 fprintf stderr pipeerror n exit 1 if pid fork 0 fprintf stderr forkerror n exit 1 elseif pid 0 close fd 1 子进程关闭写端else close fd 0 父进程关闭读端exit 0 7 4 1管道 3 管道的读写操作由于管道是一种特殊文件 用户在使用中完全可以像读写普通文件一样使用read和write对管道进行读写 7 4 1管道 读管道规则 关闭管道的写端 close fd 1 读出 read fd 0 buf size 读出后关闭管道的读端 close fd 0 写管道规则 关闭管道的读端 close fd 0 写入 write fd 1 buf size 写入后关闭管道的写端 close fd 1 include include includeintmain intn fd 2 pid tpid charout 40 if pipe fd 0 printf pipeerror exit 1 if pid fork 0 printf forkerror exit 1 elseif pid 0 子进程读管道 close fd 1 sleep 5 子进程睡眠5秒read fd 0 out 30 printf Child Readingfromthepipe s n out else 父进程写管道 close fd 0 write fd 1 Thisistheinput n 30 printf parent writetopipesuccessfully n wait pid exit 0 7 4 1管道 例子 利用两个管道进行双向通信 实现父子进程协作把整数x从1加到10 分析 创建两个管道 pipe1 父 子 pipe2 子 父 fork 产生子进程父进程 close pipe1 READ close pipe2 WRITE 子进程 close pipe1 WRITE close pipe2 READ include include include include defineMAXLINE1024 defineREAD0 defineWRITE1main void intx pid tpid intpipe1 2 pipe2 2 pipe pipe1 创建管道pipe pipe2 pid fork if pid 0 printf createprocesserror n exit 1 if pid 0 子进程 close pipe1 WRITE close pipe2 READ do read pipe1 READ elseif pid 0 父进程 close pipe2 WRITE close pipe1 READ x 1 do write pipe1 WRITE 7 4 2消息队列 消息队列是一系列连续排列的消息 保存在内核中 通过消息队列的引用标识符来访问 消息队列所传递的消息由两部分组成 structmsgbuf longmsgtype 消息的类型charmsgtext 1024 所传递的数据 7 4 2消息队列 1 msgget功能 用于创建或打开一个消息队列 函数原型 include include includeintmsgget key tkey intflags 返回值 调用成功 返回消息队列的引用标识符qid 调用失败 则返回 1 7 4 2消息队列 1 msgget参数 key 表示所创建或打开消息队列的键 flags 表示函数的操作类型 IPC CREAT 用于创建原来不存在的的队列 IPC CREAT 0777 设置权限位IPC EXCL 用于测试文件是否存在 若文件已存在则返回EEXIST IPC NOWAIT 不阻塞例如 创建一个key为45的消息队列 qid msgget 45 IPC CREAT 0666 7 4 2消息队列 2 msgsnd功能 向一个消息队列发送消息 函数原型 include include includeintmsgsnd intqid structmsgbuf ptr size tnbytes intflags 返回值 调用成功 返回0 调用失败 则返回 1 7 4 2消息队列 2 msgsnd参数 qid 消息队列的引用标识符 ptr 缓冲区指针 指向要发送的消息 nbytes 表示缓冲区最大可接收的消息正文的长度 字节数 flags 指定消息队列满时的处理办法 IPC NOWAIT 如果消息队列满或其他原因无法发送 则不等待 立即返回 1 0 如果消息队列满或者其他资源无法发送消息 则进程等待 一直到消息发送出去为止 7 4 2消息队列 3 msgrcv功能 从指定的消息队列中接收消息 函数原型 include include includeintmsgsnd intqid structmsgbuf ptr size tnbytes longtype intflags 返回值 调用成功 返回接收到的消息数据的长度 字节数 调用失败 则返回 1 7 4 2消息队列 3 msgrcv参数 qid 消息队列的引用标识符 ptr 指针 接收的消息将被存放到ptr所指向的缓冲区 nbytes 表示缓冲区最大可接收的消息正文的长度 字节数 flags 指定消息队列满时的处理办法 type 表示要接受的消息的类型 7 4 2消息队列 4 msgctl功能 实现对消息队列的具体控制操作 函数原型 include include includeintmsgsnd intqid intcmd structmsqid ds buf 返回值 调用成功 返回接收到的消息数据的长度 字节数 调用失败 则返回 1 7 4 2消息队列 4 msgctl参数 qid 消息队列的引用标识符 cmd 表示调用该函数希望执行的操作 根据不同的cmd值 可完成不同的操作 IPC RMID 删除消息队列IPC STAT 获得该消息队列的msqid ds结构 保存于buf指向的缓冲区 例如 将消息队列从内核中删除 msgctl qid IPC RMID 0 查看消息队列当前的状态 structmsqid dsst msgctl qid IPC STAT include include include includeintmain intarg char argv intmq pid tpid structmsgbuf longmtype charmtext 40 in out if mq msgget IPC PRIVATE IPC CREAT 0777 1 printf Erroropenningmessagequeue n exit 1 if pid fork if pid 1 printf Failedtoforkthechild n exit 1 in mtype 2 父进程strcpy in mtext Thisistheinput n msgsnd mq 7 4 3信号 信号是一种进程间通信的机制 其最大的特点是异步 进程在执行期间的任何时刻都有可能接收到信号 信号通常是用于要求进程打断常规的运行而处理另一些事件 因此 信号的捕获与处理也称为系统的 软中断 机制 7 4 3信号 1 信号的使用Linux系统中为软中断设立了一批信号 进程执行中可使用这些信号调整执行步骤和内容 这些信号在系统内部有具体的编号 并且安排了默认处理程序 除了系统预定义的信号外 通常系统还允许用户自定义信号 用来执行特殊的应用 信号拥有自己特定的名字 均以SIG开始 它们在头文件中被定义为一个正整数 这些正整数被称为信号编号 signalnumber 7 4 3信号 7 4 3信号 7 4 3信号 2 signal功能 接收或捕获信号 并可以编写程序对这种信号做特殊处理 函数原型 includevoid signal intsignumber void func int int 参数 signumber 信号编号 func 指向调用函数的函数指针 用来指定当进程接收到指定信号时执行的函数 7 4 3信号 2 signal返回值 调用成功 返回值为函数指针 同func 调用失败 则返回 1 include include includevoidterminatehandler intsignumber intmain void charbuffer1 100 buffer2 100 inti if signal SIGTERM for fgets buffer1 sizeof buffer1 stdin for i 0 i 97 includeintmain voidcatchint intsigno inti if signal SIGINT 7 4 3信号 3 kill功能 用于向某一给定进程或进程组发送信号 函数原型 include include includeintkill pid tpid intsignumber 参数 pid 表示kill函数发送信号对象的进程号或进程组号 signumber 信号编号 7 4 3信号 3 kill返回值 信号发送成功 返回值0 信号调用失败 则返回 1 例子 将终止信号发送给96号进程 kill 96 9 kill 96 SIGKILL intmain pid tchild intstatus retval if child fork 0 perror fork exit EXIT FAILURE printf Child sPID d n child if child 0 sleep 20 exit EXIT SUCCESS else if waitpid child include include include include include includeintmain pid tpid intnum if pid fork 0 perror fork exit EXIT FAILURE elseif pid 0 sleep 30 else printf SendingSIGCHLDto d n pid num kill pid SIGCHLD if num 0 perror kill SIGCHLD elseprintf dstillalive n pid printf Killing d n pid if kill pid SIGTERM 0 perror kill SIGTERM waitpid pid NULL 0 exit EXIT SUCCESS 7 4 4共享内存 共享内存是两个或多个进程共享同一块内存区域 并通过该内存区域实现数据交换的进程间通信机制 通常是由一个进程开辟一块共享内存区域 然后允许多个进程对此区域进程访问 由于不需要中间介质 而是数据由内存直接映射到进程地址空间 因此共享内存是最快速的进程间通信机制 7 4 4共享内存 1 shmget功能 创建一个新的共享内存 或者打开一个已存在的共享内存 函数原型 include include includeintshmget key tkey intsize intflags 返回值 调用成功 返回共享内存区的标识符 调用失败 则返回 1 7 4 4共享内存 1 shmget参数 key 表示所创建或打开的共享内存的键值 IPC PRIVATE 表示创建一个新的共享内存 IPC CREAT 如果key值已存在 则打开共享内存 否则新建共享内存size 表示共享内存区域的大小 只在创建一个共享内存时有效 flags 调用函数的操作类型及设置访问权限 7 4 4共享内存 2 shmat功能 把一个共享内存区附加到调用进程的地址空间中 函数原型 include include includechar shmat intshmid char shmaddr intflags 返回值 调用成功 返回共享内存区的实际地址 调用失败 则返回 1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 天津团员考试试题及答案
- 2025年高压低压电工特种作业操作证进网许可证考试题库(附答案)
- 2025年高校教师资格证之《高等教育心理学》练习题库完整答案详解
- 2025年高级会计师岗位面试真题及答案解析
- 2025年高等院校逻辑学考试真题及答案
- 言语治疗期末试题及答案
- 下属企业公章管理办法
- 网格化管理办法模板
- 绿茶叶种植管理办法
- 规范小型船艇管理办法
- 基孔肯雅热防控知识培训课件
- 海外仓合同范本
- 麻黄现行管理办法
- 市级防汛物资管理办法
- 试油操作规程详解
- 《研学旅行指导师实务》课件-第6章 基(营)地研学课程操作
- 2025年心理辅导员职业资格考试试卷及答案
- 肺炎护理考试试题及答案
- 2025届安徽省蒙城县英语七下期末考试试题含答案
- 肩关节脱位的治疗讲课件
- 极地车辆轻量化复合材料结构-洞察阐释
评论
0/150
提交评论