Chinaunix首页 | 论坛 | 博客
  • 博客访问: 688536
  • 博文数量: 240
  • 博客积分: 3616
  • 博客等级: 大校
  • 技术积分: 2663
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-21 23:59
文章分类

全部博文(240)

文章存档

2013年(6)

2012年(80)

2011年(119)

2010年(35)

分类: LINUX

2010-11-05 17:17:13

#include
#include
#include
#include
#include
void my_func(int signum)//自定义的信号处理函数
{
 printf("If you want to quit,please try SIGQUIT\n");
}
int main()
{
 sigset_t set,pendset;
 struct sigaction action1,action2;
 if(sigemptyset(&set)<0)//初始化信号集为空
 {
  perror("sigemptyset");
 }
 if(sigaddset(&set,SIGQUIT)<0)//将相应的信号加入信号集
 {
  perror("sigaddset");
 }
 if(sigaddset(&set,SIGINT)<0)
 {
  perror("sigaddset");
 }
 if(sigprocmask(SIG_BLOCK,&set,NULL)<0)//设置信号集屏蔽字
 {
  perror("sigprocmask");
 }
 else
 {
  printf("block\n");
  sleep(5);
 }
 if(sigprocmask(SIG_UNBLOCK,&set,NULL)<0)
 {
  perror("sigprocmask");
 }
 else
 {
  printf("unblock\n"); 
 }
 while(1)//对相应的信号进行循环处理
 {
  if(sigismember(&set,SIGINT))
  {
   sigemptyset(&action1.sa_mask);
   action1.sa_handler=my_func;
   sigaction(SIGINT,&action1,NULL);
  }
  else if(sigismember(&set,SIGQUIT))
  {
   sigemptyset(&action2.sa_mask);
   action2.sa_handler=SIG_DFL;
   sigaction(SIGTERM,&action2,NULL);
  }
   
 
 }

}
/*------------------------------------------
notes:
1.信号集函数组
(1)函数说明
使用信号集函数组处理时涉及一系列的函数,这些函数按照调用的先后次序可分为以下
几个大功能模块:创建信号集合,登记信号处理器以及检测信号.
其中,创建信号集主要用于创建用户感兴趣的信号,其函数包括以下几个.
.sigemptyset:初始化信号集合为空
.sigfillset:初始化信号集合为所有信号的集合。
.sigaddset:将指定信号加入到信号集合中去。
.sigdelset:将指定信号从信号集中删除。
.sigismember:查询指定信号是否在信号集合之中。
登记信号处理器主要是用于决定进程如何处理信号。这里要注意的是,信号集里的信号并
不是真正可以处理的信号,只有当信号的状态处于非阻塞状态时才真正起作用。因此,首先
就要判断出当前阻塞能不能传递给该信号的信号集。这里首先使用sigprocmask函数判断检
测或更改信号屏蔽字,然后使用sigaction函数用于改变进程接收到特定信号之后的行为。
检测信号是信号处理的后续步骤,但不是必须的。由于内核可以在任何时刻向某一个进程
发出信号,因此,若该进程必须保持非中断状态并且希望将某些信号阻塞,这些信号就处于
"未决"状态(也就是进程不清楚它的存在)。所以,在希望保持非中断进程完成相应的任务之
后,就应该将这些信号阻塞。sigpending函数就允许进程检测"未决"信号,并进一步决定对
它们作何处理。
2.创建信号集合的函数格式
1)所需头文件 :#include
2)函数原型:
int sigemptyset(sigset_t *set)
int sigfillset(sigset_t *set)
int sigaddset(sigset_t *set,int signum)
int sigdelst(sigset_t *set,int signum)
int sigismember(sigset_t *set,int signum)
3)函数输入参数
set:信号集
signum:指定信号值
4)函数返回值
成功:0(sigismember成功返回1,失败返回0)
出错:-1
3.sigprocmask函数语法要点:
1)所需要的头文件:#include
2)函数原型:
int sigprocmask(int how,const sigset_t *set,sigset_t *oset)
3)函数输入参数
how:决定函数的操作方式
SIG_BLOCK:增加一个信号集合到单前的阻塞集合之中
SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合
SIG_SETMASK:将当前的信号集合设置为信号阻塞集合
set:指定信号集
oset:信号屏蔽字
4)函数返回值
成功:0(sigismember成功返回1,失败返回0)
出错:-1
此处,若set是一个非空指针,则参数how表示函数的操作方式;若how为空,则表示忽略此
操作。
4.sigaction函数语法要点:
1)所需要的头文件:#include
2)int sigaction(int signum,const sigaction *act,struct sigaction *oldact)
3)函数输入参数
signum:信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号
act:指向结构sigaction的一个实例的指针,指定对特定信号的处理
oldatc:保存原来对相应信号的处理
4)函数返回值
成功:0
出错:-1
5.sigaction的定义:
struct sigaction
{
void (*sa_handler)(int signo);
sigset_t sa_mask;
int sa_flags;
void (*sa_restore)(void);  
}
sa_handler是一个函数指针,指定信号关联函数,这里除了可以是用户自定义的处理函数
外,还可以为SIG_DFL(采用确省的处理方式)或SIG_IGN(忽略信号)。它的处理函数只有一
个参数,即信号值。
sa_mask是一个信号集,它可以指定在信号处理程序执行过程中哪些信号应当被阻塞,在调
用信号捕获函数之前,该信号要加入到信号的信号屏蔽字中。
sa_flags中包含了许多标志位,是对信号进行处理的各个选择项。它的常见可选值如下所示:
SA_NODEFER\SA_NOMASK
当捕捉到此信号时,在执行其信号捕捉函数时,系统不会自动阻塞此信号。
SA_NOCLDSTOP
进程忽略子进程产生的任何SIGSTOP,SIGTSTP,SIGTTIN和SIGTTOU信号。
SA_RESTART
可让重启的系统调用重新起作用
SA_ONESHOT\SA_RESETHAND
自定义信号执行一次,在执行完毕后恢复信号的默认动作
6.sigpending函数语法要点
1)所需要的头文件:#include
2)函数原型:int sigpending(sigset_t *set)
3)函数输入参数
set:要检测的信号集
4)函数返回值
成功:0
出错:-1
7.在处理信号时,一般遵循的操作流程如下:
1)定义信号集:Sigemptyset Sigaddset ...
2)设置信号屏蔽位:sigprocmask ...
3)定义信号处理函数:  sa_mask,sa_handler,sigaction,...
4)测试信号:Sigpending
7.实验:
[root@localhost the_eight_step]# gcc sigaction.c -o sigaction
[root@localhost the_eight_step]# ./sigaction
block
unblock
If you want to quit,please try SIGQUIT
If you want to quit,please try SIGQUIT
If you want to quit,please try SIGQUIT
If you want to quit,please try SIGQUIT
If you want to quit,please try SIGQUIT
需要按Ctrl+c进行中断
-----------------------------------------------*/
阅读(991) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-11-07 19:09:37

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com