xml地图|网站地图|网站标签 [设为首页] [加入收藏]

时限信号掩码便是储存在此其间一个实信号聚焦

1 #include <unistd.h>
2 
3 /* 如果之前没有设置alarm返回0,否则返回之前
4 设置的alarm所剩余的秒数 */
5 unsigned int alarm(unsigned int seconds);

sigaction

 

sigsuspend

pause函数的调用会堵塞调用进度直到调用过程捕获到二个实信号。

alarm函数允许大家设置七个机械漏刻,那几个定时器在今后有个别时间点触发,这一个停车计时器触发后会发生三个SIGALRM时域信号,此实信号的私下认可管理情势是终结进度。

 

通过user_interrupt 判定是不是等待的SIGUSQashqai1复信号已到达,sigsuspend再回来时将经过随机信号掩码设置为她被调用前的值,由此我们最后索要将增加mask移除掉。

图片 1

 1 extern char* sys_siglist[]; 数组索引为功率信号值, 数组成分值为实信号名。

我们能够透过sigaction方法检查并更正特定非确定性信号的管理情势(action)。他是前期sinal函数的代表版本。

正如此前大家关系的,进度供给丰富的权柄才具向另一个历程发送实信号,一流客商能够向其余进度发送模拟信号。对于其余客商,能够发送非功率信号的基本法则是:发送进程的真人真事客户Id(real user Id)或有效率户Id(effective user Id卡塔尔(英语:State of Qatar)必得等于采取进程的真实顾客Id或有功能户Id。假若达成扶助 _POSIX_SAVED_IDS的话,系统会检查接收进度的saved set-user-ID并非立见成功效户Id。关于发送能量信号权限的三个古怪景况是:要是待发送非功率信号是SIGCONT,那么发送进度能够将实信号发送给他所属会话下的任何进度。

频域信号与时限信号名的转移:

1 #include <unistd.h>
2 
3 /*Returns: -1 with errno set to EINTR*/
4 int pause(void);

sigprocmask 不扶植八线程意况。

 

#include <unistd.h>

/*通过set返回发送给当前进程但被阻塞的信号*/
int sigpending(sigset_t* set);

对此kill函数,pid有以下各个差异的取舍:

 

图片 2

发送实信号

  假若贰个拥塞时限信号在经过消释它的隔开前产生多次,那么unix内核也独有会向经过下发一遍那几个功率信号。POSIX并从未规准期域信号下发到进程的后生可畏风流罗曼蒂克,可是与经过这段日子气象相关的非时限信号会较先达到进度。

Signal Names and Numbers

 

 1 sigset_t mask, oldmask;
 2 
 3 …
 4 
 5 /* Set up the mask of signals to temporarily block. */
 6 sigemptyset (&mask);
 7 sigaddset (&mask, SIGUSR1);
 8 
 9 …
10 
11 /* Wait for a signal to arrive. */
12 sigprocmask (SIG_BLOCK, &mask, &oldmask);
13 while (!usr_interrupt)
14   sigsuspend (&oldmask);
15 sigprocmask (SIG_UNBLOCK, &mask, NULL);

等候频域信号到达的二个清爽而保障地情势是先拥塞那几个能量信号然后采取sigsuspend。

像我们从前提到的,分歧非随机信号的数额大概会当先多个整数的bit位所能表示的实信号数量。POSIX规范定义了sigset_t类型用来代表非确定性信号集,并采纳上边包车型客车5个函数来处理连续信号集:

#include <unistd.h>

/*若oact不为空,函数通过oact返回当前signo的action
 * 若act不为空,则修改signo的当前action*/
int sigaction(int signo, const struct sigaction* restrict act,
struct sigaction* restrict oact);

struct sigaction{
   void (*sa_handler)(int);    /*addr of signal handler, 
                                 or SIG_IGN or SIG_DFL */
   sigset_t sa_mask;           /*additional signals to block*/
   int sa_flag;                /*signal options*/

   /*alternate handler*/
   void (*sa_sigaction)(int,siginfo_t *, void *);         
};                                    
1 #include <signal.h>
2 
3 /* return 0 if OK, -1 on error */
4 int kill(pid_t pid, int signo);
5 
6 /* return 0 if OK, -1 on error */
7 int raise(int signo);

  一个风云能够使二个实信号发送给叁个历程,这么些事件能够是硬件特别,能够是软件条件触发,可以是极端发生复信号,也足以是二个kill函数调用。当连续信号发生后,内核日常会在进度表中装置某种方式的注解(flag)。大家能够认为当进程中的时域信号管理函数被触发的时候认为功率信号下达到了(delivered)这一个进程。从信号产生到非非确定性信号下达成进程这段之间,随机信号被以为是挂起状态(pending)。过程具备拥塞功率信号下达的选项。假使三个绿灯实信号要发送给二个经过,而且非确定性信号的处理形式是私下认可管理还是被进程捕获,那么那么些功率信号将直接处于挂起状态(pending)直到那么些历程将时域信号设置成非阻塞状态或将时限信号的管理格局改为忽视。操作系统在连续信号下达(delivered)的时候决定如哪管理那个窒碍时域信号,并不是在非实信号产生的时候。那样做允许进度在时限信号下达前矫正随机信号的管理情势。

信号集

 

  • SIG_BLOCK: set包罗其它的大家想不通的能量信号
  • SIG_UNBLOCK:set包括大家想要消亡拥塞的实信号
  • SIG_SETMASK:使用set替代进度近日时域信号掩码

 

POSIX规范定义时域信号值为0的功率信号为空时限信号(null signal)。它能够用于通过kill函数来检查评定某豆蔻梢头进程是还是不是留存。kill函数在吸取值为0的频限信号后会进程符合规律的错误检查,但是不会发送此能量信号。因而我们能够通过 kill(pid, 0卡塔尔(قطر‎ 来判定进程id为pid的进程是还是不是存在。然则, UNIX系统在认依时期后会循环利用进度IDs,所以经过pid检查出来的历程未必真的是您以为的丰硕进度(即函数调用时,通过pid查询到的进程未必会是您感到的那多少个进度)。别的kill函数不是原子的,当kill函数再次来到时,有超大希望被发送连续信号的历程已经终结。

 

 

  时域信号平时用于一些相持复杂的前后相继, 通晓怎样及为哪儿理功率信号对于UNIX高等编制程序是必备的。

能够行使kill函数向三个进程或进度组发送实信号。raise函数允许进度给她协和发送时域信号。

#include <signal.h>

/*
  如果oset不为空,那么此进程信号掩码之前的值会被复制到oset中。
  如果set为空,那么此进程的信号掩码不会被更改,而信号掩码的当前值
  也不会复制到oset中。
*/
int sigprocmask(int how, const sigset_t* restrict set,
    sigset_t* restrict oset);
 1 #include <unistd.h>
 2 
 3 /*All four return 0 if OK, -1 on error*/
 4 
 5 /*清空set信号集中的所有信号*/
 6 int sigemptyset(sigset_t* set);
 7 /*使set包含所有信号*/
 8 int sigfillset(sigset_t* set);
 9 /*将信号signo加入到信号集set中*/
10 int sigaddset(sigset_t* set, int signo);
11 /*从信号集set中删除signo*/
12 int sigdelset(sigset_t* set, int signo);
13 
14 /*Returns 1 if true, 0 if false, -1 on error*/
15 int sigismember(const sigset_t* set,  int signo);
  1. pid > 0: 时域信号被发送给进度号为pid的进程
  2. pid == 0: 复信号被发送给全体进度组Id等于发送者进度组的进度(即发送给发送进程所属进度组下的有所进度),前提是出殡和下葬进程有权力将时域信号发送给该进度况且该进程不是系统经过。
  3. pid < 0: 时域信号被发送给进度组Id为pid相对值的历程组下的具备进度,前提是出殡和下葬进程有权力发送非随机信号到该进程何况该进度不是系统经过。
  4. pid == -1: 功率信号被发送给发送进度有权力发送的装有进度,但不含有系统经过。

  每个进度都有一个功率信号掩码(signal mask),它定义了二个脚下被卡住发送到该进度的非确定性信号的集中。大家能够觉得那么些掩码对于各类只怕下发到该进度的实信号有贰个与之相应的bit位,对于三个加以的功率信号的话,倘使与之相应的bit位是开发状态,那么意味着那几个功率信号当前应处于堵塞状态。进度能够透过sigprocmask来检查并退换他脚下的非非确定性信号掩码。因为功率信号的数额是有极大恐怕超越叁个卡尺头正bit位位数的,全部POSIX标准定义了四个称作sigset_t的数据类型,它含有了具有实信号集。非确定性信号掩码就是积攒在这里中间七个复信号聚焦的。

风流罗曼蒂克经到了alarm所设置的时间点,内核就能够发送alarm信号,而由于计算机调节延时进度那个时候可能还不可能得到到此实信号管理的调控权。每一个进程中独有二个alarm石英钟。当大家调用alarm时,假诺当前路程以前注册的石英钟还没到期,那么此函数重返此前机械钟距到期剩余的秒数,并且在此之前注册的石英钟会被这么些新的挂钟值取代。此外,要是从前注册的挂钟还没到期况且新登记的石英钟值为0的话,那么此前注册的时钟会被吊销。

数组sys_siglist可以协理大家合营时限信号与时域信号名:

 

 1 #include <signal.h>
 2 
 3 /* 如果msg不为空,则向stderr 输出msg紧跟一个冒号加一个空着在加信号描述;如果msg为空则只向stderr输出信号描述*/
 4 void psignal(int signo, const char* msg);
 5 
 6 void psiginfo(const siginfo_t info, const char* msg);
 7 
 8 /*获取信号描述*/
 9 char* strsignal(int signo);
10 
11 void sig2str(int signo, char* str);
12 void str2sig(const char* str, int* signop);

sa_flags:

当使用sigaction改变signo的action时,如果sa_handler指向了三个能量信号处理函数(SIG_IGN和SIG_DFL除此而外),sigaction函数会将sa_mask指向的功率信号集结在这里个功率信号管理函数(sa_handler)被调用前踏入到当前经过掩码中,当复信号管理函数重临时,进程的功率信号掩码会苏醒为他原本的值。那样,使大家能够在数字信号管理函数被调用是堵塞意气风发部分数字信号的达到。黄金年代旦大家为二个频域信号安装了action, 那么对于那几个功率信号这么些action将直接处于安装状态,除非我们应用sigaction方法料定的改动可它。

kill & raise

 

#include <signal.h>

/*
   将当前进程信号掩码设置为sigmask,
   函数返回后将进程掩码恢复为调用前
   的值, 该函数总是返回-1,并设置
   errno 为 -1
*/
int sigsuspend(const sigset_t* sigmask);

 

sigpending

sigprocmask

 

 

 

how参数的值指明如何改过非功率信号掩码:

叁个进程的功率信号掩码是指被阻止下发到此进度的具有时域信号的集纳。进程能够检查并转移他的实信号掩码。

函数调用 raise(signo卡塔尔国;  等同于 kill(getpid(卡塔尔(قطر‎, signo卡塔尔国; 。

alarm & pause

 sigsuspend 可用于等待指定期域信号的到达,他的常用用法如下:

总结

本文由澳门威尼斯老品牌发布于威尼斯注册,转载请注明出处:时限信号掩码便是储存在此其间一个实信号聚焦