Chinaunix首页 | 论坛 | 博客
  • 博客访问: 969090
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-12-08 11:41:30

10.3 signal function

#include

 

void (*signal(int signo, void (*func)(int)))(int);

 

Returns: previous disposition of signal (see following) if OK, SIG_ERR on error

1.这个函数用来安装signalhandler。当然有些信号是不能有我们自定义handler的如SIGSTOPSIGKILL.这个函数声明有点晦涩,可以这样看:

Typedef void (*funcPtr)(int);

funcPtr signal(int signo, funcPtr func);

2.这个函数有个缺点,即,我们没有方法测试当前进程是否针对某个signal设置了handler,而能通过修改当前进程对某个signalhandler函数后才能通过返回值得到旧的handler函数。所以使用sigactionsignal要方便,如下是signal的例子:

void sig_int(int), sig_quit(int);

if (signal(SIGINT, SIG_IGN) != SIG_IGN)

  signal(SIGINT, sig_int);

if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)

   signal(SIGQUIT, sig_quit);

上述返回值的一些定义:

#define SIG_ERR (void (*)())-1
#define SIG_DFL (void (*)())0
#define SIG_IGN (void (*)())1

3.一个刚启动的进程,其各个signalhandler要么忽略,要么都是默认的。一个fork出来的子进程它会继承父亲设置的对一些signalhandler。然而一旦子进程执行了exec调用,这个继承就被冲掉了,因为父进程里handler函数的地址对于新的exec的进程显然没有什么意义了。

4.下面有一个使用SIGUSR1信号的例子:

Figure 10.2. Simple program to catch SIGUSR1 and SIGUSR2
#include "apue.h"
 
static void sig_usr(int);   /* one handler for both signals */
 
int
main(void)
{
    if (signal(SIGUSR1, sig_usr) == SIG_ERR)
        err_sys("can't catch SIGUSR1");
    if (signal(SIGUSR2, sig_usr) == SIG_ERR)
        err_sys("can't catch SIGUSR2");
    for ( ; ; )
        pause();
}
 
static void
sig_usr(int signo)      /* argument is signal number */
{
    if (signo == SIGUSR1)
        printf("received SIGUSR1\n");
    else if (signo == SIGUSR2)
        printf("received SIGUSR2\n");
    else
        err_dump("received signal %d\n", signo);
}

注意,pause()函数相当于使本执行体wait,仅当收到一个signal时才返回,且返回-1, errno被设置为EINTR,表明pause被打断了。或者本进程直接收到了不能被捕获的结束信号而结束(就不会再返回了)。所以我们可以加上如下代码:

If( pause() == -1 )

       Puts(“we received a signal”);

但是,一般的用法是使用pause()来作为一个执行体的结束点,即pause()使其等待信号,并且设置了相应的handler,等信号以来,相应的handler被处理后,pause返回,然后就结束。有个问题,我怎么只知道是收到了那个信号呢?

结果如下:

$ ./a.out &                   start process in background
   [1]      7216                 job-control shell prints job number and process ID
   $ kill -USR1 7216             send it SIGUSR1
   received SIGUSR1
   $ kill -USR2 7216             send it SIGUSR2
   received SIGUSR2
   $ kill 7216                   now send it SIGTERM
   [1]+  Terminated    ./a.out

 

阅读(885) | 评论(0) | 转发(0) |
0

上一篇:10.2 signal concepts

下一篇:10.4 unreliable signals

给主人留下些什么吧!~~