资源预览内容
第1页 / 共94页
第2页 / 共94页
第3页 / 共94页
第4页 / 共94页
第5页 / 共94页
第6页 / 共94页
第7页 / 共94页
第8页 / 共94页
第9页 / 共94页
第10页 / 共94页
亲,该文档总共94页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第六讲 UNIX进程通信,1 基本概念,通信分为两类: 控制信息的传递: 低级通信 大批量数据的传递: 高级通信,1 基本概念,2基本的通信方式,(a)主从式通信: 通信的双方存在一种隶属关系,(b)会话式通信: 通信进程双方采用请求应答的方式进行通信,1 基本概念,2基本的通信方式,(c)消息或邮件通信: 通信双方处于一个平等地位,发的消息通过消息系统或邮件系统进行大批量数据传递。,1 基本概念,2基本的通信方式,(d)共享存储区通信:进程之间采用进程通信信息共享存储区的通信方式来完成进程间的通信。,2 UNIX系统进程通信方式,基本通信:早期的UNIX系统采用,简单的信息传递,协调进程之间的同步和互斥。 管道通信:大批量的数据传送,有名管道和无名管道。 IPC :采用消息方式进行进程间通信。,2 UNIX系统进程通信方式,1基本通信 锁文件通信: 通信双方在某个指定目录中查找是否有个双方约定的文件存在,并以此来决定通信的动作以及对应的逻辑。进程用对“锁文件创建与否”状态的判定和设置完成一个进程到另一个进程之间的通信。 (2) 记录锁定文件通信 即是通过对记录(文件中连续的字节组成特定的数据)的锁定来实现进程通信。 (3)信号 使用软中断信号的通信方式。信号可以做预先的说明,用户使用时只需要根据信号的约定来完成进程之间的通信。,3 信号处理,基本概念,信号是UNIX操作系统用来通知进程发生了某种事件的一种手段 信号也称为软中断,它提供了一种处理异步事件的方法 信号也可以用于进程之间进行通信和实现进程同步处理,信号的定义: 信号是传送给进程的一种事件通知,UNIX系统为每一种可能的事件定义了一组信号,每一个信号有一个信号名,名字均以SIG打头,3 信号处理,很多种情况会产生信号,当用户在终端按下某些键时,产生终端生成的信号,例如: 按下Delete键或者Ctrl-c通常产生一个中断信号 SIGINT,这是停止正在运行的程序的一种常用手段,硬件例外会产生信号,例如: 零作为除数、非法存储器访问等。这种情况通常是由硬件而不是UNIX内核检测到的,但由内核向发生此错误的哪个进程发送相应的信号,比如发生非法存储器访问时,信号SIGSEGV将被内核发送到执行了该非法访问的进程。,如果发生了某种必须让进程知道的情况时也会生成信号。这里的情况不是硬件产生的,而是软条件,例如: 当进程设置的定时器到期时将生成SIGALRM信号 当进程向一个管道写数据,而此管道已不存在读数据方时,生成SIGPIPE信号,某些系统调用将产生信号,例如 kill函数将允许进程发送任何信号给本进程,其他的进程或者进程组 raise函数能够发送任何一个信号给调用它的进程,3 信号处理,生成信号的事件可以归并为三大类,1.程序错误 例如零作除数、非法存储器访问等,2. 外部事件 例如用户按下Delete键、定时器到期等,3. 显式请求 进程主动调用kill函数或者raise函数,3 信号处理,同步信号和异步信号,信号的生成可以是同步的,也可以是异步的。,同步信号与程序中的某个具体操作相关并且在那个操作进行时同时产生。 多数程序错误生成的信号是同步的,例如除零错或内存访问错 由进程显示请求而生成的给自己的信号也是同步的,例如raise系统调用,异步信号是接收该信号的进程控制之外的事件生成的信号 一般外部事件总是异步的生成信号 作用于其他进程的kill系统调用也异步地生成信号 异步信号可以在进程运行任意时刻产生,进程无法预期信号到达的时刻,3 信号处理,对信号的处理,无论是同步还是异步信号,信号发生时,系统对信号可以采用3种处理方式,忽略信号 大部分信号都可以被忽略,只有2个除外SIGSTOP和SIGKILL。这两个信号是为了给root用户提供杀掉或停止任何进程的一种手段。,调用默认动作 系统为每种信号规定了一个默认动作,如果用户进程没有为某个信号设置句柄,则该信号到达时,对该信号的处理由UNIX内核来完成。通常的默认动作有: core dump, 终止进程,忽略信号,进程挂起等几种。,捕获信号 需要告诉UNIX系统内核,当该信号出现时,调用专门提供的一个函数,类似于MFC中的事件函数的概念。这个函数称为信号句柄,或者简称为句柄,它专门对产生信号的事件作出处理。系统调用sigal为特定信号设置信号句柄,3 信号处理,UNIX系统中常用的信号,3 信号处理,UNIX系统中常用的信号,3 信号处理,指定和改变信号的动作,对于每一种信号,进程可以指定要么忽略它,要么采取默认动作,或者为它指定一个自定义的捕获函数;进程也可以在任何时候对一个信号重新指定其动作或者回到其原先的动作。,3 信号处理,系统调用 signal函数 void* signal(int sig, void(* func)(int) ) ;,参数sig是个整数,指明该系统调用处理哪一个信号 参数func指明信号sig发生时,系统可以采取的3种动作之一:,常数 SIG_DFL 指明对信号采用默认动作 常数 SIG_IGN 指明该信号发生时,系统将忽略它 信号句柄地址 用户自定义的信号处理函数,信号发生时,系统将调用该函数进行处理,3 信号处理,void* signal(int sig, void(* func)(int) )函数的注意事项,由signal函数建立的信号句柄应当是一个仅有一个整形参数且没有返回值的函数,其整形参数指明该生成的信号,signal函数的返回值是指向信号sig的前一次有效动作的指针,当该函数调用成功,将返回SIG_DFL、SIG_IGN,或者信号句柄地址,当信号发生时,如果func指向信号句柄,系统在把控制转到信号句柄之前,将首先改变该信号的动作为SIG_DFL,如果signal调用出错,它返回SIG_ERR,唯一的错误码是EINVAL,即是sig给出的信号数非法,3 信号处理,实例:sig.c,#include void signal_handle(int the_signal); /定义一个信号句柄函数的原型 void main( void ) printf(“the process id is %dn”, getpid(); if ( signal(SIGUSR1, signal_handle ) = SIG_ERR ) err_exit(“can not catch SIGUSR1n”); if ( signal(SIGUSR2, signal_handle ) = SIG_ERR ) err_exit(“can not catch SIGUSR2n”); for( ; ; ) pause(); / pause()函数等待信号的到达 ,3 信号处理,void signal_handle(int the_signal) if ( the_signal = SIGUSR1 ) printf(“the sigal is SIGUSR1”); else if ( the_signal = SIGUSR2) printf(“the sigal is SIGUSR2”); else printf(“the received signal is %dn”, the_signal); ,%a.out& the process id is 7346 %,3 信号处理,执行上面源代码编译后的程序,并调度到后台运行,kill -USR1 7346,发送信号SIGUSR1给进程号为7346的进程,the sigal is SIGUSR1 %,后台进程7346收到SIGUSR1信号并调用信号句柄,kill -USR2 7346,发送信号SIGUSR2给进程号为7346的进程,the sigal is SIGUSR2 %,后台进程7346收到SIGUSR2信号并调用信号句柄,kill 7346,发送信号SIGTERM给进程号为7346的进程,表示要结束该进程,1+Terminated a.out& %,后台进程7346收到SIGTERM信号,调用默认信号动作,该动作终止进程,#include void catch_sig_int( ing signo ) /* signal( SIGINT, catch_sig_int );*/ printf(“SIGINT was caught,user pressed keydeleten”); /* signal( SIGINT, catch_sig_int );*/ void main() int i = 0; signal( SIGINT, catch_sig_int ); for( i=0; i5; i+ ) printf(“ Sleep called #%dn”, i ); sleep(1); printf(“exitingn”); ,3 信号处理,信号的生成,信号的产生,可以使用三个系统调用 int raise( int sig ); 功能:给进程自己发送一个信号 int kill( pid_t pid, int sig ); 功能:发送一个信号给进程或者进程组 unisigned int alarm( unsigned int seconds ); 功能:在seconds秒后向自己发送一个SIGALRM信号.,3 信号处理,raise函数的实例,#include void sig_tstp_handle( int sig ) signal(SIGTSTP, SIG_DFL); /*做清理动作,SIGTSTP是一个交互停止信号,类似于停止信号SIGSTOP*/ . . . . . raise(SIGTSTP); void main() signal(SIGTSTP, sig_tstp_handle); . . . . . . . /事务处理代码 ,3 信号处理,kill函数的实例,3 信号处理,alarm函数的实例,main() unsigned int i; alarm(1); for(i=0; ; i+) printf(“I=%d“,i); ,3 信号处理,信号操作:有时候我们希望进程正确的执行,而不想进程受到信号的影响,比如我们希望上面那个程序在1秒钟之后不结束.这个时候我们就要进行信号的操作.,信号操作最常用的方法是信号屏蔽,即是进程屏蔽掉某些指定的信号. 信号屏蔽要用到信号集的概念和几个重要的函数.,信号集 该数据结构可以表示系统支持的每一个信号. 在 signal.h中定义了 sigset_t 来描述信号集,3 信号处理,主要的信号操作函数 int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t *set,int signo); int sigdelset(sigset_t *set,int signo); int sigismember(sigset_t *set,int signo); int sigprocmask(int how,const sigset_t *set,sigset_t *oset);,!注意:信号操作函数 不能对信号SIGKILL和SIGSTOP进行阻塞屏蔽,3 信号处理,以一个实例来解释使用这几个函数. int main() sigset_t intmask; sigemptyset( ,3 信号处理,等待信号:如果程序是由外部事件所驱动的,或者使用信号进行同步,则需要等待信号的到达.,UNIX系统提供函数pause() 和 sigsuspend()来等待信号,int pause(void); 功能:在新的信号到来之前,暂时停止程序的运行 int sigsuspend( sigset_t *sigmask); 功能:将进程信号的掩码替换并暂时中止进程,
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号