一、产生信号
代码:
1#include<stdio.h>
2#include<unistd.h>
3int main()
4 {
5 printf("%d\n",getpid());
6 while(1)
7 {
8 }
9 return 0;
10 }
(1)终端输入
[admin@localhost SIGNAL]$ ./Signal
^C
[admin@localhost SIGNAL]$ ./Signal
^\退出 (core dumped)
(2)调用系统函数
#include<signal.h>
int kill(pid_t pid,int signo);
int raise(intsigno);
<1>
[admin@localhost ~]$ ps aux |grep Signal
admin 4902 0.0 0.0 1868 332 pts/0 S+ 05:13 0:00 ./Signal
admin 4904 0.0 0.0 5980 736 pts/1 S+ 05:13 0:00 grep Signal
[admin@localhost ~]$ kill -SIGSEGV 4902
<2>
[root@www SIGNAL]# ./Signal &
[1] 2538
[root@www SIGNAL]# 2538
kill -11 2538
[root@www SIGNAL]#
[1]+ 段错误 (core dumped)./Signal
<3>raise函数
1#include<stdio.h>
2#include<unistd.h>
3int main()
4 {
5 printf("%d\n",getpid());
6 while(1)
7 {
8 sleep(5);
9 raise(2);
10 }
11 return 0;
12 }
<4>abort函数
(3)软件条件实现
unsigned int alarm(unsigned int seconds);
二、阻塞信号
信号递达、信号未决、信号阻塞
每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理
动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。
Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。
<1>信号集操作函数
#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);
<2>. sigprocmask
调用函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
返回值:若成功则为0,若出错则为-1
<3> sigpending
#include <signal.h>
int sigpending(sigset_t *set);
sigpending读取当前进程的未决信号集,通过set参数传出。调用成功则返回0,出错则返回-1。
代码:
1 #include<stdio.h>
2 #include<signal.h>
3 void Printpending(sigset_t *s)
4 {
5 int i=0;
6 for(;i<32;i++)
7 {
8 if(sigismember(s,i))
9 {
10 printf("1");
11 }
12 else
13 {
14 printf("0");
15 }
16
17 }
18 printf("\n");
19 }
20 int main()
21 {
22 sigset_t s,p;
23 sigemptyset(&s);
22 sigset_t s,p;
23 sigemptyset(&s);
24 sigemptyset(&p);
25 sigaddset(&s,2);
26 sigprocmask(SIG_BLOCK,&s,NULL);
27 while(1)
28 {
29 sigpending(&p);
30 Printpending(&p);
31 fflush(stdout);
32 sleep(1);
33 }
34
35 return 0;
36 }
结果:
[admin@localhost SIGNAL]$ ./signal_group
10000000000000000000000000000000
10000000000000000000000000000000
10000000000000000000000000000000
10000000000000000000000000000000
^C10100000000000000000000000000000
10100000000000000000000000000000
10100000000000000000000000000000
10100000000000000000000000000000
10100000000000000000000000000000
10100000000000000000000000000000
^\退出 (core dumped)
三、捕捉信号
函数:
#include <signal.h>
int sigaction(int signo, const struct sigaction *act, struct
sigaction *oact);
pause
#include <unistd.h>
int pause(void);
实现一个my_sleep(5)
代码:
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<signal.h>
4 void sig_alarm()
5 {
6
7 }
8 unsigned int my_sleep(unsigned int seconds)
9 {
10 struct sigaction act;
11 struct sigaction oact;
12 unsigned int unslept=0;
13 act.sa_flags=0;
14 sigemptyset(&act.sa_mask);
15 act.sa_handler=sig_alarm;
16 sigaction(SIGALRM,&act,&oact);
17 alarm(seconds);
18 pause();
19 unslept=alarm(0);
20 sigaction(SIGALRM,&oact,NULL);
21
22 return unslept;
23 }
24 int main()
25 {
26 while(1)
27 {
28 my_sleep(5);
29 printf("5 seconds passed\n");
30 }
31 return 0;
32 }
结果:
[admin@localhost SIGNAL]$ ./my_sleep
5 seconds passed
5 seconds passed
5 seconds passed
^C
转载于:https://blog.51cto.com/youngyoungla/1770725