signal函数说明

 

c traps and pitfalls 对signal函数解释得非常详细。

<signal.h> 中

void ( *signal( int sig, void (* handler)( int ))) ( int );
int (*p)();
这是一个函数指针, p所指向的函数是一个不带任何参数, 并且返回值为int的一个函数.
int (*fun())();
这个式子与上面式子的区别在于用fun()代替了p,而fun()是一个函数,所以说就可以看成是fun()这个函数执行之后,它的返回值是一个函数指针,这个函数指针(其实就是上面的p)所指向的函数是一个不带任何参数,并且返回值为int的一个函数.

void (*signal(int signo, void (*handler)(int)))(int);就可以看成是signal()函数(它自己是带两个参数,一个为整型,一个为函数指针的函数), 而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带一个整型参数,并且返回值为void的一个函数.

在写信号处理函数时对于信号处理的函数也是void sig_fun(int signo);这种类型,恰好与上面signal()函数所返回的函数指针所指向的函数是一样的.

void ( *signal() )( int );

signal是一个函数, 它返回一个函数指针, 后者所指向的函数接受一个整型参数 且没有返回值, 仔细看, 是不是siganal( int signo, void (*handler)(int) )的第2个参数了, 对了, 其实他所返回的就是 signal的第2个信号处理函数, 指向信号处理函数, 就可以执行函数了( signal内部时, signal把信号做为参数传递给handler信号处理函数, 接着 signal 函数返回指针, 并且又指向信号处理函数, 就开始执行它)

那么,signal函数的参数又是如何呢?signal函数接受两个参数:一个整型的信号编号,以及一个指向用户定义的信号处理函数的指针。我们此前已经定义了指向用户定义的信号处理函数的指针sfp:

void (*sfp)(int);
sfp 的类型可以通过将上面的声明中的sfp去掉而得到,即void (*)(int)。此外,signal函数的返回值是一个指向调用前的用户定义信号处理函数的指针,这个指针的类型与sfp指针类型一致。因此,我们可以如下声明signal函数:
void (*signal(int, void(*)(int)))(int);
同样地,使用typedef可以简化上面的函数声明:
typedef void (*HANDLER)(int);
HANDLER signal(int, HANDLER);

下面来看一个简单的例子:

#include <signal.h> 
#include <unistd.h> 
#include <stdio.h>

void sigroutine(int dunno) 
{ /* 信号处理例程,其中dunno将会得到信号的值 */
	switch (dunno) 
	{ 
	case 1: 
		printf("Get a signal -- SIGHUP\n "); 
		break; 
	case 2: 
		printf("Get a signal -- SIGINT\n "); 
		break; 
	case 3: 
		printf("Get a signal -- SIGQUIT\n "); 
		break; 
	}
	return; 
}

int main() 
{ 
	printf("process id is %d\n ",getpid()); 
	signal(SIGHUP, sigroutine); //* 下面设置三个信号的处理方法 
	signal(SIGINT, sigroutine); 
	signal(SIGQUIT, sigroutine); 
	for (;;) ; 
}
 
其中信号SIGINT由按下Ctrl-C发出,信号SIGQUIT由按下Ctrl-发出。该程序执行的结果如下:
[zcm@t #29]$make
gcc -g   -c -o a.o a.c
gcc -g -o a a.o
[zcm@t #30]$./a
process id is 7666
^C Get a signal -- SIGINT
^Z
[1]+  Stopped                 ./a
[zcm@t #31]$ps aux|grep ./a
root      1164  0.0  0.0  13320   748 ?        S<sl 20:24   0:00 /sbin/audispd
root      1275  0.0  0.0   1880   580 ?        Ss   20:24   0:00 /usr/sbin/acpid
68        1395  0.0  0.0   3384   948 ?        S    20:24   0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
root      1669  0.0  0.5  22344  6028 ?        Ss   20:26   0:00 /usr/sbin/abrtd
root      1697  0.0  0.0   2240   320 ?        Ss   20:26   0:00 /usr/sbin/atd
root      1742  1.6  2.1  32496 21752 tty1     Rs+  20:26   1:47 /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-eLxmfB/database -nolisten tcp vt1
zcm       2388  0.0  1.4  34860 15316 ?        S    20:32   0:00 python /usr/share/system-config-printer/applet.py
zcm       7666  7.5  0.0   1728   356 pts/0    T    22:15   0:06 ./a
zcm       7714  0.0  0.0   5816   724 pts/0    S+   22:17   0:00 grep ./a
[zcm@t #32]$kill -HUP 463
bash: kill: (463) - 没有那个进程
[zcm@t #33]$kill -HUP 7666
[zcm@t #34]$kill -9 7666
[zcm@t #35]$ps aux|grep ./a
root      1164  0.0  0.0  13320   748 ?        S<sl 20:24   0:00 /sbin/audispd
root      1275  0.0  0.0   1880   580 ?        Ss   20:24   0:00 /usr/sbin/acpid
68        1395  0.0  0.0   3384   948 ?        S    20:24   0:00 hald-addon-acpi: listening on acpid socket /var/run/acpid.socket
root      1669  0.0  0.5  22344  6028 ?        Ss   20:26   0:00 /usr/sbin/abrtd
root      1697  0.0  0.0   2240   320 ?        Ss   20:26   0:00 /usr/sbin/atd
root      1742  1.6  2.1  32496 21752 tty1     Rs+  20:26   1:48 /usr/bin/Xorg :0 -nr -verbose -auth /var/run/gdm/auth-for-gdm-eLxmfB/database -nolisten tcp vt1
zcm       2388  0.0  1.4  34860 15324 ?        S    20:32   0:00 python /usr/share/system-config-printer/applet.py
zcm       7746  0.0  0.0   5816   756 pts/0    S+   22:18   0:00 grep ./a
[1]+  已杀死               ./a
[zcm@t #36]$

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用和提供了关于signal函数的两种用法的示例代码。signal函数是一个用来处理信号的函数,其原型为sigaction(int signum, const struct sigaction* act, struct sigaction* oldact)。参数signum表示要处理的信号的编号,act是一个指向结构体sigaction的指针,用来指定信号处理函数,oldact是一个指向结构体sigaction的指针,用来保存之前的信号处理函数signal函数在接收到指定的信号时,会调用act所指定的信号处理函数。 在引用的示例代码中,signal(SIGINT, SIG_IGN)表示忽略了SIGINT信号,即在接收到SIGINT信号时不做任何处理,程序会一直运行下去。 在引用的示例代码中,signal(SIGINT, signal_handler_fun)表示在接收到SIGINT信号时,会调用signal_handler_fun函数来处理该信号。signal_handler_fun是一个自定义的函数,其作用是输出"aaa"并换行。 除了signal函数外,还有一个同名的命令行工具/bin/kill可以用来向指定进程发送信号。例如,/bin/kill -9 15213表示向进程编号为15213的进程发送信号9。 综上所述,signal函数用来处理信号,可以通过指定信号处理函数来对接收到的信号做出相应的操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Signal ()函数详细介绍](https://blog.csdn.net/qq_58011370/article/details/119456193)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Unix信号详解(Signal的信号说明)](https://blog.csdn.net/github_33873969/article/details/77744382)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值