====================信号,进程间的通信===========================
一。回顾上一节课程的内容
1.信号一般处理非正常情况,是软件中断技术
硬件异常信号:除数为0,段错误,总线错误,文件访问失败,还有一些快捷键:ctrl+c
软件异常信号:kill settimer raise ...等 在程序中认为的写出来的
可靠信号(实时信号):支持队列
不可靠信号(非实时信号):不支持排队(即相同信号多次发送会抛弃同一类型的信号)
2.具有特殊意义的信号都是不可靠信号,可靠的信号都是用户自定义的。所以基本上我们学的都是不可靠信号。
3.信号大部分默认动作是终止,而子进程发给父进程的信号才会默认是忽略的。
4.如果要改变一个默认信号的动作,这就需要我们去注册一个信号处理函数:signal(信号名,函数/宏名)
SIG_IGN忽略掉该信号,SIG_DFL执行默认动作, SIG_ERR等价与void*(-1)可判断注册是否成功
5.pause信号等待函数,让进程去睡觉,知道有信号来。其返回值永远为-1,表示有信号过来了。
6.SIGKILL SIGSTOP不可被忽略和重写,只有默认才可以。
7.子进程会继承父进程的信号处理方式。 因为子是copy父的东东所以一样。除非子用exec方式,那么都是以默认的方式来执行,仅仅在父亲中被忽略的信号即使exec也会被忽略。
8.sigaction函数的功能同signal函数一样,注册安装一个函数,只是选项更多,更方便一些操作。
8.1防止其他信号来打扰我这个信号处理函数:action.mask = set; set是一个信号集变量,有相应的增,删,清空,填充,是否存在函数来操作。(这样就在该注册函数中屏蔽了信号集中的信号)
9.第一个信号在处理,第二个信号被阻塞,第三个信号就会被丢弃(同一类型的信号哦)
action.sa_flags=SA_NOMASK; //不屏蔽当前信号的再次到来,即同一个信号来了,就立马执行,即使之前的信号没有执行完毕。即不理会之前的东东了。呵呵 .mask 是屏蔽一个信号集。
.sa_flags=SA_ONESHOT 仅用一次安装函数,然后就执行默认的东东了。
10.信号与系统调用:
如果系统调用快,则信号来了会等他执行完毕在处理信号
如果系统调用慢,那么信号就不会等,那么系统调用会失败。可以用.sa_flag=sa_restart(大写)来:等信号处理完毕之后,就会重新调用那个被打断的系统调用。(这样就分为可重入函数,和不可重入函数:比如使用了全局变量的函数)
****如果我们在信号中频繁用全局变量,则可能会出问题********
11.alarm(5) 告诉内核5秒后发个SIGALAM信号过来。alarm(0);取消计时 ,此时之前的alarm(5)会失效覆盖掉了。呵呵
12.kill()发送信号给进程。
燃烧吧。。。。。。。。燃烧吧。。。。。。。
12.进程组:便于管理,可统一发送信号。 setpgid() getpgid() setpgrp() getpgrp() 属于unixc下的函数,非标准的。
13.同kill函数效果:sigqueue 与kill不同之处是:它可以带个联合类型的值 union sigval {int ,void*}
==========================进程间的通信(IPC)===============================
1. 管道(是unixIPC最古老的形式) ls 查看,,,是p类型文件。大小为0的文件,因为他只起到传输数据作用,而非保存数据。
mkfifo a.pipo 管道文件
c管道函数:管道读不出会阻塞,与一般的文件读写是不一样的,所以判断也不一样。呵呵
2.无名管道(仅仅适用于父子进程)
pipe() 打开一个管道文件,获得2个文件描述(读,写)
父写,子读(父的读关闭,子的写关闭)
子写,父读(父的写关闭,子的读关闭)
3.XSI IPC 消息队列,信号,共享内存
1.共享内存段
即多个进程共同映射一个物理内存段,读写可以分工,大家都共享这段内存,所以都可以读取和写入。呵呵