美文网首页
linux-10 -信号(2)+IPC

linux-10 -信号(2)+IPC

作者: vera姐姐 | 来源:发表于2016-05-16 11:15 被阅读51次

    信号:信号的发送函数/信号集和信号屏蔽/介绍一个sigaction()/信号应用的相关函数:sleep(),usleep() 计时器

    进程间通信IPC -总体概念和IPC之间的管道

    信号的发送方式:

    1.键盘发送(少部分)

    ctrl+c 信号2

    ctrl+\ 信号3

    2.硬件错误/代码问题(少部分)

    段错误 信号11

    总线错误 信号SIGBUS Linux是信号7

    整数除以0 信号8 SIGFPE

    3.Unix命令kill发送信号(全部)

    kill -信号 进程PID

    4.Unix的系统函数发送信号(有些函数是全部,有些是部分)

    raise() kill() alarm() sigqueue()...

    主要介绍:kill() 结束alarm()

    & 如何判断某进程时候有发信号的权限?

    信号0 可以用于测试,因为信号0 没有实际意义,所以法过去后没有后果,只是知道是否能发。

    raise()只能给本进程发信号,功能可以被kill()完全替代,等价于kill(getpid(),signum).

    int kill(pid_t pid,int signum)

    功能:给所有有发送权限的进程发信号

    参数:pid就是信号的接收进程,包括:

    >0 发送给特定的某个进程(进程ID=pid)

    0  发送给本组进程

    -1 发送给所有的进程(有发送权限的所有进程)

    <-1 发送给进程组ID=|pid|的所有进程

    返回:成功为0,失败为-1

    多个同名进程可以用  killall+进程名 杀掉同名进程

    sleep(int seconds)函数会让进程休眠n秒,但当有 未忽略的信号到来的时候,休眠会被终端,返回剩余秒数。

    usleep()函数也可以让进程休眠,但以微秒 作为休眠时间单位。

    alarm()函数严格来说或不算信号发送函数,只能给自己发特定的信号(闹钟信号)。可以用来定时做任务。alarm(0)取消所有的闹钟。

    信号集

    一个二进制位能代表一个信号,1代表有,0代表没有。理论上说64位整数(long long int)就能存放所有的信号。但考虑到后期的扩展性,用了一个超级大的整数去代表所有的信号的有无。类型是 sigset_t(信号集)。倒数第n位就代表信号n

    信号集是一种数据结构,逻辑数据结构/物理数据结构/运算数据结构。逻辑结构就是 在人的思维中的结构。物理结构就是计算机的底层如何区实现(内存是否连续,连续就是数组方式,不连续就是链式表方式);运算结构就是提供哪些功能,也就是需要提供哪些函数。运算结构一般都会包括:1.内存的分配和回收函数(数据结构的创建和销毁) 2.元素的添加(追加或插入)包括:单添和群添 3.元素的删除(从最后开始删除,从指定位置删除,从开始删除),包括单删和群删 4.元素的修改(不是所有的数据结构都需要) 5.元素的查询和取出

    6.特殊的需要,不如排序等。

    信号集提供的功能函数:

    信号集的创建和销毁系统已经完成,没有函数。信号集的函数有5个:

    sigaddset() -添加一个信号(把对应二进制 位  置1)

    sigdelset() -删除一个信号(把对应二进制 位  置0)

    sigemptyset() -清空信号集(清0)

    sigfillset() -填满信号集(全部置1)

    sigismember() -是否包含某个信号(查询)

    信号屏蔽:

    有些关键代码不希望被信号打断,而程序员无法控制信号的到来。因此信号屏蔽技术就用来解决关键代码不被信号打断的问题。信号屏蔽不是屏蔽信号的到来,而是采用:信号可以来,但来了以后暂时不做处理,等关键代码执行完毕后,解除了信号屏蔽再进行处理。(延迟处理)。

    如何实现/解除 信号屏蔽?

    函数sigprocmask() 可以屏蔽信号或解除屏蔽

    屏蔽时把 新的需要屏蔽 的信号传入,同时允许把 旧的屏蔽的信号(信号屏蔽字)带出来;解除屏蔽时,把旧的 信号屏蔽字再次 设置进去即可。

    int sigpromask(int how,sigset_t *new,sigset_t * old)

    功能:屏蔽信号或是解除屏蔽

    参数:how就是屏蔽的方式,包括:

    SIG_BLOCK  相当于加法,屏蔽老的 加上 新的

    SIG_UNBLOCK 相当于减法,屏蔽老的减去新的

    SIG_SETMASK -相当于赋值,屏蔽新的,和老的无关

    在使用时,用SIG_SETMASK即可。

    new 就是需要屏蔽的信号集

    old 就是用来返回之前屏蔽的信号集。用来解除屏蔽

    返回值:成功为0,失败为-1

    可靠信号在信号屏蔽时不会丢失,不可靠信号如果同一个信号多次到来会丢失;信号9不会被屏蔽。

    信号的应用之一 ----计时器(了解)

    Linux系统中,每个进程都支持3个计时器:真实/虚拟/实用。其中真实计时器 会记录程序的运行总时间。计时器的功能就是 一段时间之后 每隔一段时间 生产一个信号。系统会处理信号。

    计时器的设置和获取函数:setitimer()和getitimer()

    进程间通信(IPC)

    进程间不能通过内存直接互访。但进程之间有时候需要数据交互,因此进程间通信就非常的重要。linux系统以多进程为核心的操作系统。因此进程间通信在Linux系统中频繁的被使用。

    常见的IPC:

    1 文件

    2 信号

    3 管道

    4 共享内存

    5 消息队列

    6 信号量集(semaphore arrays)

    7 网络编程(socket编程)

    ........

    其中,共享内存/消息列队和信号量集 遵循相同的规范,在编程上有很多相似之处。通称为XSI IPC。

    管道是Unix IPC最古老的方式之一,现在较少使用。管道是以管道文件 作为交互的媒介。管道文件是一种特殊的文件,touch vi open() 都无法创建管道文件。 mkfifo()函数或mkfifo命令可以创建管道文件。管道文件中不会保存数据,只是数据的中转站。因此管道文件在只有读或者只有写的时候,会阻塞,直到读写管道都畅通时才会中断数据。

    历史上的管道是半双工的(数据不同时传递,单向)。现在有全双工的(双向)。

    管道分为有名管道和无名管道,有名管道可以用于任何进程之间的IPC,而无名管道只能用于fork()创建父子进程之间IPC。有名管道就是程序员建立管道文件,然后IPC。无名管道就是内核处理管道文件,然后IPC。

    IPC至少写两个程序 。

    有名管道的使用步骤:

    1.享用mkfifo命令或mkfifo() 创建管道文件。

    2.用open()打开管道文件

    3.读写管道文件

    4.关闭文件描述符

    5.如果必要的化,remove()删除管道文件。

    2,3,4与读写普通文件一样。

    相关文章

      网友评论

          本文标题:linux-10 -信号(2)+IPC

          本文链接:https://www.haomeiwen.com/subject/xvrbrttx.html