信号量与异步通知

2019-07-14 10:39发布

信号量与异步通知 一 信号量原理概述 1 LINUX当中的信号处理机制 进程管理块(PCB)中有几个字节的比特位,每一个比特位代表着一种信号。进程首先要注册一个函数用于处理对应的信号,一般来说调用signal或者是signalaction函数。当用kill指令向某一个进程发送信号,就会陷入内核,通过进程号(PID)取得对应得PCB,然后将PCB中对应信号得比特位置位。在内核返回用户空间之前,会进行PCB的信号比特位检查,检查有置位时,就调用前面注册得相对应得函数进行处理。 2 发送信号 使用kill指令发送信号时,必须给出的参数有PID。内核通过PID索引到PCB,然后将对应得比特位置位,即完成了信号的发送。一般来说,对于异步通知,信号的发送是驱动程序需要完成的任务。 3 信号屏蔽 每个进程都有一个信号集,用于描述哪些信号被屏蔽,这个信号集叫做信号掩码。信号屏蔽并非让进程不响应信号,只是延迟了信号的到达,只要屏蔽解除,信号响应会继续进行。 4 捕捉信号 进程对信号的响应就是捕捉到了信号。在进程初始化时,每一个信号都会被注册一个默认的处理函数。我们可以调用signal来注册自己的处理函数用于取代默认处理函数。这个signal也可以说是信号捕捉函数。捕捉信号是用户程序的任务,驱动程序不会干涉。 二 信号量操作 1 信号量的捕获 #include typedef void (*sighandler_t)(int) signalhandler_t signal(int signum, sighandler_t handler) #include int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact) 其中signum 表示要操作的信号量 act 是新的操作方式 oldact是旧的操作方式 struct sigaction { void (*sa_handler)(int); void (*sa_action)(int, siginfo_t *,void *); sigset_t mask; int sa_flag; void (*sa_restorer)(void); } 成员说明: sa_handler是信号量处理函数 sa_sigaction 用于获取信号量详细信息的函数 mask 用于信号处理函数期间屏蔽信号的信号掩码 sa_flag 用于控制信号处理行为的标志位 sa_restorer 已废弃,不使用 2 信号的发送 原理:在用户程序当中,调用了fasync函数时给出两个命令标志,分别为F_SETDOWMF_SETFLset fasync list),前者会调用f_setdown函数,该函数将当前进程的PID记录到file->f_owner当中去。后者调用会导致调用setfl函数,该函数调用到驱动程序当中得fasync函数,在fasync函数中会调用fasync_hlper函数,这个函数将当前进程加入到fasync链表当中去。当调用到kill_fasync 函数发送信号时,就会历遍这个链表,并且调用sed_sigio函数发送信号。(sed_sigio(fowm,fa->fa_fd,band))。