第8章 进程间通信.ppt_第1页
第8章 进程间通信.ppt_第2页
第8章 进程间通信.ppt_第3页
第8章 进程间通信.ppt_第4页
第8章 进程间通信.ppt_第5页
已阅读5页,还剩66页未读 继续免费阅读

下载本文档

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

文档简介

1、第八章通过进程间通信、8.1项目目标8.2进程间通信概述8.3管道通信8.4信号通信8.5信号量8.6共享存储器8.7消息队列8.8项目应用、8.1项目目标、本章学习,掌握进程间通信的常用方法。 经过修订以实现数据采集与显示通信系统的中心数据采集过程与数据传输过程之间的数据通信。 本章的知识点:在Linux系统中,同时存在多个进程时,这些异步进程之间的通信问题(数据和协作等)是必要的。 Linux提供管道、信号、消息队列、共享内存、信号量、套接字等通信机制。 本章将进行详细的学习。8.2进程间通信概述、为什么需要进程间通信、数据传输一个进程需要将数据发送到另一个进程、在共享资源的多个进程之间共

2、享相同资源通知事件的一个进程需要将消息发送到另一个进程、一个进程需要将消息发送到另一个进程8.2概述进程间通信、Linux上的进程通信手段基本上从UNIX平台上的进程通信手段继承。 对UNIX的发展有着重大贡献的两个主力AT,一旦创建了一个管道,就会创建两个文件描述符。 filedis0用于读取管道,filedis1用于写入管道。 8.3.1关闭无名管道和管道,只需关闭两个文件描述符即可。 可以使用常规的close函数逐个关闭。 无名流水线使用特征:只能用于具有亲缘关系的进程间通信(例如父子进程)。 在半双工通信模式下,固定的读和写管道可以视为特殊文件,其读和写可以使用普通的read和writ

3、e等函数。 但是,它只存在于内核的内存区域,而不是普通文件。8.3.1无名管路、# include # include # include int main () int pipe _ FD 2; if (pipe (pipe _ FD )0)打印机(pipecreateerrorn )。 返回- 1; 电子打印(管道创建成功); 克洛斯(pipe _ FD0); 克洛斯(pipe _ FD1); 8.3.1匿名管道和管道用于不同的进程间通信,通常先创建管道,然后使用fork函数创建子进程。 此子进程继承由父进程创建的管道。8.3.1无名管道、子进程写入和父进程读取命名管道:8.3.1无名管道

4、、管道读写注意事项只有在管道读取端存在时,才向管道写入数据是有意义的。 否则,向管道写入数据的过程从内核接收SIGPIPE信号。 向管道写入数据时,如果管道缓冲区中有空闲空间,写入过程将尝试向管道写入数据。 如果读取过程不从管道缓冲区读取数据,则写入将被阻止。 父子进程在运行时不能保证优先级。 可以使用sleep ()解析父子进程,以确保关闭相应的文件描述符。8.3.1匿名管道和管道读取/写入注意事项通过打开两个管道,可以创建双向管道。 但是,必须在子进程中正确设置文件描述符。 必须在系统调用fork ()之前调用pipe ()。 否则,子进程将不会继承文件描述符。 使用半双工管道时,相关进程

5、必须共享相关的祖先进程。 由于管道存在于系统内核中,因此不能检索在创建管道的进程的祖先进程中不存在的进程。 在有名的管子里不是这样的。 程序分析: pipe_rw.c工作:模仿半双工管道程序写全双工管道程序,命名管道和无名管道基本相同,不同之处在于:无名管道只能使用父子工艺,但是通过给管道命名,不相关的工艺命名管道创建: # include # includeintmkfifo (const char * pathname,mode_t mode) pathname:FIFO文件名mode :属性(请参见文件)8.3.2命名管道FIFO,8.3.2命名管道FIFO,对于要打开以供读取的管道,可

6、将open ()设置为O_RDONLY,对于要打开以供写入的管道,可将open ()设置为O_WRONLY 在管路的读写中有可能发生块,这里的非块标志可以用open ()函数设为O_NONBLOCK。 在读取过程中,如果此管道被阻止并打开,并且当前FIFO中没有数据,则读取过程将阻止它,直到有数据写入。 如果此管道以无阻塞方式打开,则无论FIFO中是否有数据,读取过程都会立即执行读取操作。 也就是说,如果FIFO中没有数据,则读取函数立即返回0。 命名8.3.2管道FIFO。 如果在写入过程中管道被阻塞并打开,写入将被阻塞直到数据被写入。 如果此管道以无阻塞方式打开,并且无法写入所有数据,则会

7、部分写入读取操作或调用失败。 像管道一样,为了读取而写入未打开的FIFO时,生成信号SIGPIPE。 如果FIFO的最后一个写入过程关闭了FIFO,则会为该FIFO的读取过程生成文件结束标志。 删除管道:可以使用unlink函数删除命名管道。 实例分析: fifo_write.c、fifo_read.c、8.3.2命名管道fifo、FIFO相关错误消息: EACCES (无权限) EEXIST (指定文件不存在) ENAMETOOLONG (路径名长) ENOSPC (文件系统可用空间不足) ENOTDIR作为进程间通信的机制,更重要的是,信号始终用于中断进程的正常运行并处理更多异常。 信号是

8、异步的,过程不知道信号什么时候到达。 进程可以处理信号,也可以向特定进程发送信号。 每个信号都有以SIG开头的名称。 例如,SIGABRT是进程异常终止信号。8.4管道通信,许多条件可以生成一个信号:用户按下特定终端键时生成信号。 在终端上按下Ctrl c键,通常会发生中断信号(SIGINT )。 这是停止丢失的控制程序的方法。 硬件异常发生信号:除数为0、无效的内存访问等。 这些条件通常由硬件检测并通知内核。 然后,内核会在条件发生时为正在运行的进程生成适当的信号。 例如,将为执行无效存储访问的进程生成SIGSEGV。 进程可以使用kill(2)函数向另一进程或进程组发送信号。 当然,也有接

9、收进程和发送进程的所有者必须相同,或者发送进程的所有者必须是超级用户的限制。8.4.2信号源,许多条件可生成一个信号:用户可用kill(1)命令向其他过程发送信号。 这个程序是kill函数的接口。 此命令通常会终止失控的后台进程。 检测到发生任何软件条件并将其通知相关进程时,也会生成信号。 这里,指的是软件条件,而不是硬件生成条件(例如除以0 )。 例如,SIGURG (上传网络连接中未规定的波特率数据)、SIGPIPE (在管道读取过程结束后写入该管道)和SIGALRM (由该过程设置的超时警报时间) 、8.4.2信号源、不可靠的信号: Linux信号机制基本上从Unix系统继承。 初始Un

10、ix系统中的信号机构相对简单且原始,然后实际上由于暴露了一些问题,在初始机构中建立的信号被称为“不可靠的信号”,并且信号值小于SIGRTMIN的不可靠信号(131 )。 每次处理信号时,与该信号相对应的处理函数都会变为默认值。 但是,现代的Linux经过改进,信号处理函数始终由用户指定或系统默认。 有信号丢失的可能性。不可靠的信号不支持信号排队,同样的信号多次发生,只要程序还没有处理该信号,实际上只处理一次该信号。8.4 .信号源、7.3.3信号类型、可靠信号:信号值在SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。 实时信号和非实时信号: Linu

11、x现在定义了64种信号(将来有可能扩展),前32种是非实时信号,后32种是实时信号。 非实时信号是不支持排队且不可靠的信号,实时信号是支持排队并且可靠的信号。 信号队列意味着无论发生多少次信号,信号处理函数都会调用相同的次数。 7.3.3信号的种类、7.3.3信号的种类、7.3.3信号的种类、7.3.4信号的处理可以在系统出现某个信号时要求以下三种方式中的某一种进行操作。 (1)无视该信号。 大多数信号可以用这种方式处理,但两个信号不会被忽略。 SIGKILL和SIGSTOP两种信号都不能忽略的原因是,为超级用户提供了终止或停止进程的可靠方法。 此外,如果忽略由硬件异常引起的信号(如非法的存储

12、访问或除以0的信号),则不定义进程的行为。 (2)捕捉信号。 为此,通知内核在发生任何信号时调用用户函数。 用户函数允许用户对这些事件执行他们想要执行的操作。 捕获SIGCHLD信号表示子进程已完成,因此该信号捕获函数可以调用waitpID来获取子进程的进程id及其完成状态。 (3)执行系统默认动作。 大多数信号的系统默认行为是终止此过程。 7.3.4.1信号的处理缺省情况下,每个信号都有缺省行为。 这是当进程没有为此信号指定处理程序时内核对信号的处理。 有五个默认的动作。 异常终止(abort ) :在进程的当前目录下,将进程的地址空间内容、寄存器内容保存到名为core的文件中,终止进程。

13、退出:直接退出进程而不生成核心文件。 忽略:忽略该信号。 停止:停止进程。 继续(continue ) :如果进程锁定,则继续执行进程。 否则,忽略信号。 7.3.4.2信号的处理捕获。 当系统捕获信号时,可以忽略信号、使用指定的处理函数处理信号或使用系统的默认方法。 信号处理的主要方法有两种。 一种方法是使用简单的signal函数,另一种方法是使用信号集函数组。 (1)信号处理机制,# include void (*信号,void (*函数) ) (int )返回: 如果发生错误,则为SIG _ errtypedefvoid (* sighandler _ t ) (输入)符号(输入符号、符

14、号) (c )接收该信号后调用函数的地址:捕获此信号称为该信号。 该函数称为“信号处理程序”(signal handler )或“信号捕获函数”(signal-catching function )。在实例分析中,#包括#包括_函数(输入符号_ no ) if (符号_ no=符号)打印else if (符号_ no=符号quit )打印机int main ()打印机(waitingforsignalsignalsintorsigquitn )。 符号,符号,符号; 信号(单位,我的函数); pause (); exit(0); (1)信号处理机构将从终端CTRL C产生的信号: # incl

15、ude # include int main ()信号忽略。 (1)休眠(1); 返回0; /程序执行后,如果忽略来自Ctrl c的SIGINT信号,则Ctrl c不能结束该过程,(1)Signal处理机构接受信号的默认处理,接受默认处理是信号处理器# include # include #。 返回0; (1)信号处理机制,注意:信号主要采用前32种非实时信号处理信号不能传送附加数据的信号处理机制,有些特殊情况注册一个信号处理函数,处理完毕后又发生了同样类型的信号。 此时,如果信号处理函数正在处理中,处理未完成,则会产生其他类型的信号。 这个时候,怎么处理好呢? (2)sigaction、Linux支持更加结实、更新的信号处理函数sigaction # include;const struct sigaction * act、struct sigaction *oldact ); 第一个signum指定需要处理(捕捉)的信号(SIGKILL和SIGSTOP除外)。 第二残奥仪表act (结构)可以设置信号处理方案,而act可以为空。 先设定的信号处理方式保

温馨提示

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

评论

0/150

提交评论