我是靠谱客的博主 无辜小甜瓜,这篇文章主要介绍可靠信号的用法,现在分享给大家,希望可以做个参考。

signal() 函数只能提供简单的信号安装操作,使用该函数处理信号比较简单,只要把要处理的信号和处理函数列出即可。signal() 函数主要用于从 Unix 继承过来的不可靠、非实时信号的处理,并且不支持信号传递信息。Linux 提供了功能更强大的 sigaction() 函数,此函数可以用来检查和更改信号处理操作,可以支持可靠、实时信号的处理,并且支持信号传递信息。

先看 kill() 的升级版:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <signal.h> /* 功能:给指定进程发送信号 */ int sigqueue(pid_t pid, int sig, const union sigval value); /* 参数: pid: 进程号。 sig: 信号的编号,这里可以填数字编号,也可以填信号的宏定义,可以通过命令 kill -l ("l" 为字母)进行相应查看。 value: 通过信号传递的参数。 */ union sigval { int sival_int; void *sival_ptr; }; /* 返回值: 0:成功 -1:失败 */

在看 signal() 的升级版:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <signal.h> /* 功能:检查或修改指定信号的设置(或同时执行这两种操作)。*/ int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); /* 参数: signum:要操作的信号。 act: 要设置的对信号的新处理方式(设置)。 oldact:原来对信号的处理方式(设置)。 如果 act 指针非空,则要改变指定信号的处理方式(设置),如果 oldact 指针非空,则系统将此前指定信号的处理方式(设置)存入 oldact。 */ /* 现在 struct sigaction 被定义得比较复杂,简化一下如下: */ struct sigaction { /*旧的信号处理函数指针*/ void (*sa_handler)(int signum) ; /*新的信号处理函数指针*/ void (*sa_sigaction)(int signum, siginfo_t *info, void *context); /*信号阻塞集*/ sigset_t sa_mask; /*信号处理的方式*/ int sa_flags; /*这个暂时不用管*/ void (*sa_restorer) (void); }; /* sa_handler、sa_sigaction:信号处理函数指针,和 signal() 里的函数指针用法一样,应根据情况给 sa_sigaction、sa_handler 两者之一赋值,其取值如下: SIG_IGN:忽略该信号 SIG_DFL:执行系统默认动作 处理函数名:自定义信号处理函数 信号处理函数定义为如下形式: void (*sa_sigaction)( int signum, siginfo_t *info, void *context ); signum:信号的编号。 info:记录信号发送进程信息的结构体。 context:可以赋给指向 ucontext_t 类型的一个对象的指针,以引用在传递信号时被中断的接收进程或线程的上下文。 sa_mask:信号阻塞集  sa_flags:用于指定信号处理的行为,它可以是一下值的“按位或”组合: SA_RESTART:使被信号打断的系统调用自动重新发起(已经废弃) SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号。 SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程。 SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。 SA_RESETHAND:信号处理之后重新设置为默认的处理方式。 SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。 */ /* 返回值: 成功:0 失败:-1 */

代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/* study.cpp 发送程序 */ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *argv[]) { if(argc >= 2) { pid_t pid,pid_self; union sigval tmp; /* 将命令参数转化为进程号 */ pid = atoi(argv[1]); /* 用命令参数作为传递值 */ tmp.sival_int = atoi(argv[2]); /* 给进程 pid,发送 SIGINT 信号,并把 tmp 传递过去 */ sigqueue(pid, SIGINT, tmp); pid_self = getpid(); printf("pid = %d, pid_self = %dn", pid, pid_self); } return 0; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/* main.c 接收程序 */ #include <signal.h> #include <unistd.h> #include <stdio.h> /* 信号处理回调函数 */ void signal_handler(int signum, siginfo_t *info, void *ptr) { printf("signum = %dn", signum); /* 发送信号的进程的进程号 */ printf("info->si_pid = %dn", info->si_pid); /* 对方传递过来的信息 */ printf("info->si_sigval = %dn", info->si_value.sival_int); } int main(int argc, char *argv[]) { struct sigaction act, oact; /* 指定信号处理回调函数 */ act.sa_sigaction = signal_handler; /* 设置阻塞集为空 */ sigemptyset(&act.sa_mask); /* 使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数。 */ act.sa_flags = SA_SIGINFO; /* 注册信号 SIGINT */ sigaction(SIGINT, &act, &oact); while(1) { printf("pid is %dn", getpid()); /* 捕获信号,此函数会阻塞 */ pause(); } return 0; }

先执行:

复制代码
1
2
3
4
[lingyun@manjaro study]$ gcc main.c -o main [lingyun@manjaro study]$ gcc study.cpp -o study [lingyun@manjaro study]$ ./main pid is 13758

再在另一个命令窗口执行:

复制代码
1
2
3
4
[lingyun@manjaro study]$ ./study 13758 777 pid = 13758, pid_self = 13761 [lingyun@manjaro study]$ ./study 13758 7775 pid = 13758, pid_self = 13762

第一个命令窗口会得到一些信息,可见接受进程接收到了发送进程发送的信号以及一些信息,如 info->si_sigval. 另外,siginfo_t *info 这个结构体里面还有很多其他信息,可以看看。

复制代码
1
2
3
4
5
6
7
8
9
10
11
[lingyun@manjaro study]$ gcc main.c -o main [lingyun@manjaro study]$ gcc study.cpp -o study [lingyun@manjaro study]$ ./main pid is 13758 signum = 2 info->si_pid = 13761 info->si_sigval = 777 pid is 13758 signum = 2 info->si_pid = 13762 info->si_sigval = 7775

 

最后

以上就是无辜小甜瓜最近收集整理的关于可靠信号的用法的全部内容,更多相关可靠信号内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部