课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部《Linux系统程序设计》理论课教案第4章进程间通信一、整章授课思路[900分钟].......................................................................................................................1.回顾、预习检查、任务、目标部分[5分钟]...................................................................................22.信号(135分钟)..................................................................................................................................总结[2分钟]...............................................................................................................................................9二、学员问题汇总.......................................................................................................................................9三、作业布置...............................................................................................................................................9课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部课时:20课时授课人:XXX本章目标熟练掌握进程间通信的方法参考资料推荐——提供参考资料及经典书籍Unix网络编程(第2卷进程间通信)了解Unix/Linux进程间通信的方式掌握和熟练运用信号编程掌握和熟练运用管道编程掌握和熟练运用文件锁编程了解IPC的基本原理掌握和熟练运用信号量编程掌握和熟练运用消息队列编程掌握和熟练运用共享内存编程本章重点信号量共享内存本章难点信号量共享内存整章授课思路【900分钟】本章依次讲解:信号的基本理论信号的发送多信号的处理管道的基本理论管道的编程使用管道的注意问题FIFO的基本理论及运用信号量的基本理论信号量编程消息队列的基本理论消息队列编程共享内存的基本概念共享内存编程1.回顾、预习检查、任务、目标部分【5分钟】根据PPT中提供的问题,逐一提问学员,注意给予学员引导,建立学员的信心。进程间通信的方法有?信号、文件锁、管道、FIFO、信号量、共享内存、消息队列课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部哪一种方法最有效,最快?共享内存哪些方法是systemVIPC?:信号量、共享内存、消息队列必须要求是亲属进程间才能通信的方法是?管道2.信号【90分钟】2.1信号的基本理论引入:由前一章节的并发编程引入进程间通信,由中断来引入信号。讲解要点:信号的基本概念信号是什么:信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还可以传递附加信息。信号是传送给进程的事件通知,它可以完成进程间异步事件的通信.导致信号产生的原因很多,但总体说来有三种可能:(1)程序错误.当硬件出现异常,除数为0或者软件非法访问等情况时发生.(2)外部事件.当定时器到达,用户按健中断或者进程调用abort等信号发送函数时方生.(3)显式请求.当进程调用kill,raise等信号发送函数或者用户执行shell命令kill传递信号时发生.同样的,当进程收到信号时有三种处理方式:(1)系统默认.系统针对不同的信号有不同的默认处理方式.(2)忽略信号.信号收到后,立即丢弃.注意信号SIGSTOP和SIGKILL不能忽略.(3)捕获信号.进程接收信号,并调用自定义的代码响应之.通过kill–l命令,向学员讲解Linux支持的信号及前31个信号和后31个信号的差别。附:不可靠信号和可靠信号(此处部分仅供教员参考)不可靠信号Linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,因此,把那些建立在早期机制上的信号叫做不可靠信号,信号值小于SIGRTMIN的信号都是不可靠信号。这就是不可靠信号的来源。它的主要问题是:进程每次处理信号后,就将对信号的响应设置为默认动作。在某些情况下,将导致对信号的错误处理;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。信号可能丢失,后面将对此详细阐述。因此,早期unix下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失。Linux支持不可靠信号,但是对不可靠信号机制做了改进:在调用完信号处理函数后,不必重新调用该信号的安装函数(信号安装函数是在可靠机制上的实现)。因此,Linux下的不可靠信号问题主要指的是信号可能丢失。可靠信号课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部随着时间的发展,实践证明了有必要对信号的原始机制加以改进和扩充。所以,后来出现的各种Unix版本分别在这方面进行了研究,力图实现可靠信号。由于原来定义的信号已有许多应用,不好再做改动,最终只好又新增加了一些信号,并在一开始就把它们定义为可靠信号,这些信号支持排队,不会丢失。同时,信号的发送和安装也出现了新版本:信号发送函数sigqueue()及信号安装函数sigaction()。POSIX.4对可靠信号机制做了标准化。但是,POSIX只对可靠信号机制应具有的功能以及信号机制的对外接口做了标准化,对信号机制的实现没有作具体的规定。信号值位于SIGRTMIN和SIGRTMAX之间的信号都是可靠信号,可靠信号克服了信号可能丢失的问题。Linux在支持新版本的信号安装函数sigation()以及信号发送函数sigqueue()的同时,仍然支持早期的signal()信号安装函数,支持信号发送函数kill()。注:不要有这样的误解:由sigqueue()发送、sigaction安装的信号就是可靠的。事实上,可靠信号是指后来添加的新信号(信号值位于SIGRTMIN及SIGRTMAX之间);不可靠信号是信号值小于SIGRTMIN的信号。信号的可靠与不可靠只与信号值有关,与信号的发送及安装函数无关。目前linux中的signal()是通过sigation()函数实现的,对于目前linux的两个信号安装函数:signal()及sigaction()来说,它们都不能把SIGRTMIN以前的信号变成可靠信号(都不支持排队,仍有可能丢失,仍然是不可靠信号),而且对SIGRTMIN以后的信号都支持排队。这两个函数的最大区别在于,经过sigaction安装的信号都能传递信息给信号处理函数(对所有信号这一点都成立),而经过signal安装的信号却不能向信号处理函数传递信息。对于信号发送函数来说也是一样的。实时信号与非实时信号前32种信号已经有了预定义值,每个信号有了确定的用途及含义,并且每种信号都有各自的缺省动作。如按键盘的CTRL^C时,会产生SIGINT信号,对该信号的默认反应就是进程终止。后32个信号表示实时信号,等同于前面阐述的可靠信号。这保证了发送的多个实时信号都被接收。实时信号是POSIX标准的一部分,可用于应用进程。非实时信号都不支持排队,都是不可靠信号;实时信号都支持排队,都是可靠信号。常见信号及其意义信号意义信号意义1)SIGHUP挂断16)SIGSTKFLT堆栈错(未用)2)SIGINTCtrl-C17)SIGCHLD子进程终止或停止3)SIGQUITCtrl-\18)SIGCONT恢复被挂起的进程4)SIGILL非法指令19)SIGSTOP停止进程5)SIGTRAP硬件失效20)SIGTSTPCtrl-Z,挂起6)SIGABRT进程异常终止21)SIGTTIN后台进程读TTY7)SIGBUS总线错误22)SIGTTOU后台进程写TTY8)SIGFPE算术失效23)SIGURGI/O管道上的紧急事件9)SIGKILL终止进程24)SIGXCPU超出CPU限量10)SIGUSR1用户自定义25)SIGXFSZ超出文件大小限量11)SIGSEGV段失效26)SIGVTALRM虚拟定时器报警12)SIGUSR2用户自定义27)SIGPROF统计信息定时器报警课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部13)SIGPIPE管道已经断裂28)SIGWINCH窗口大小变化14)SIGALRM实时报警29)SIGIO异步I/O事件15)SIGTERM终止进程30)SIGPWR电源失效进程对信号的响应进程可以通过三种方式来响应一个信号:(1)忽略信号,即对信号不做任何处理,其中,有两个信号不能忽略:SIGKILL及SIGSTOP;(2)捕捉信号。定义信号处理函数,当信号发生时,执行相应的处理函数;(3)执行缺省操作,Linux对每种信号都规定了默认操作,详细情况请参考[2]以及其它资料。注意,进程对实时信号的缺省反应是进程终止。Linux究竟采用上述三种方式的哪一个来响应信号,取决于传递给signal函数的参数。函数功能对信号指定处理方式头文件#includesignal.h函数原型typedefvoid(*sighandler_t)(int);sighandler_tsignal(intsignum,sighandler_thandler);参数意义signum指定信号的值handler指定针对前面信号值的处理,可以忽略该信号(参数设为SIG_IGN);可以采用系统默认方式处理信号(参数设为SIG_DFL);也可以自己实现处理方式(参数指定一个函数地址)。返回值成功则返回最后一次为安装信号signum而调用signal()时的handler值;失败则返回SIG_ERR。课堂案例:4.1.1信号的基本概念/sig_dfl:演示如何执行默认操作4.1.1信号的基本概念/sig_ign:演示如何忽略信号4.1.1信号的基本概念/sig_func:演示如何执行用户指定的函数验证案例:(无)2.2信号的发送引入:由信号的基本概念引入信号的发送。讲解要点:如何发送信号(1)kill系统调用:给指定的进程发送信号。函数功能对指定的进程发送信号头文件#includesys/types.h#includesignal.h函数原型intkill(pid_tpid,intsig);参数意义pidpid大于零时,pid是信号欲送往的进程的标识。pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。pid小于-1时,信号将送往以-pid为组标识的进程。课程名称:Linux系统程序设计海同ICEP2.0·产品开发培训部sig准备发送的信号代码,假如其值