进程间通信_04信号
一 概述
信号的作用是通知进程某一特定事件的发生。是一种软件中断。採用异步处理机制,即当信号发送到某个进程中的时候,操作系统会中断进程的正常处理流程。转而去进入信号处理函数进行操作,等信号处理函数完毕之后,返回中断处继续运行。
信号的发送:硬件产生(按键 或者 硬件错误) 、软件产生(程序调用kill、alarm等函数)
信号的处理:用户自己定义函数处理、系统默认方式处理、忽略。
二 常见的信号
"动作(Action)"栏 的 字母 有 下列 含义:
A 缺省动作是结束进程.
B 缺省动作是忽略这个信号.
C 缺省动作是结束进程, 而且核心转储.
D 缺省动作是停止进程.
E 信号不能被捕获.
F 信号不能被忽略.
| 信号 | 值 | 动作 |
说明 |
| SIGINT | 2 | A |
从键盘输入的中断 |
| SIGQUIT | 3 | C |
从键盘输入的退出 |
| SIGILL | 4 | C |
无效硬件指令 |
| SIGABRT | 6 | C |
非正常终止, 可能来自 abort(3) |
| SIGFPE | 8 | C |
浮点运算例外 |
| SIGKILL | 9 | AEF |
杀死进程信号 |
| SIGSEGV | 11 | C |
无效的内存引用 |
| SIGPIPE | 13 | A |
管道中止: 写入无人读取的管道 |
| SIGALRM | 14 | A |
来自 alarm(2) 的超时信号 |
| SIGTERM | 15 | A |
终止信号 |
| SIGUSR1 | 30,10,16 | A |
用户定义的信号 1 |
| SIGUSR2 | 31,12,17 | A |
用户定义的信号 2 |
| SIGCHLD | 20,17,18 | B |
子进程结束或停止 |
| SIGCONT | 19,18,25 |
|
继续停止的进程 |
| SIGSTOP | 17,19,23 | DEF |
停止进程 |
| SIGTSTP | 18,20,24 | D |
终端上发出的停止信号 |
| SIGTTIN | 21,21,26 | D |
后台进程试图从控制终端(tty)输入 |
| SIGTTOU | 22,22,27 | D |
后台进程试图在控制终端(tty)输出 |
| 信号 | 值 | 动作 |
说明 |
| SIGPOLL |
|
A |
I/O就绪事件 (Sys V). 等同于SIGIO |
| SIGPROF | 27,27,29 | A |
系统资源定时器(Profiling timer)超时 |
| SIGSYS | 12,-,12 | C |
用错误參数调用系统例程 (SVID) |
| SIGTRAP | 5 | C |
跟踪/断点自陷 |
| SIGURG | 16,23,21 | B |
套接口上出现 urgent 情况 (4.2 BSD) |
| SIGVTALRM | 26,26,28 | A |
虚拟超时时钟 (4.2 BSD) |
| SIGXCPU | 24,24,30 | C |
超过了CPU时间限制 (4.2 BSD) |
| SIGXFSZ | 25,25,31 | C | 超过了文件限制大小 (4.2 BSD) |
| 信号 | 值 | 动作 |
说明 |
| SIGEMT | 7,-,7 |
|
|
| SIGSTKFLT | -,16,- | A |
协处理器堆栈错误 |
| SIGIO | 23,29,22 | A |
I/O 有效信号 (4.2 BSD) |
| SIGCLD | -,-,18 |
|
等同于 SIGCHLD |
| SIGPWR | 29,30,19 | A |
电源无效 (System V) |
| SIGINFO | 29,-,- |
|
等同于 SIGPWR |
| SIGLOST | -,-,- | A |
文件锁丢失 |
| SIGWINCH | 28,28,20 | B |
窗体大小调整信号 (4.3 BSD, Sun) |
| SIGUNUSED | -,31,- | A |
未使用的信号 (将成为 SIGSYS) |
三 信号的产生
1 键盘产生
ctrl+c 产生 SIGINT 信号
ctrl+z 产生 SIGSTP 信号
2 shell命令产生
kill -9 15212 表示发送信号9(SIGKILL)给pid为15212的进程。
3 调用函数产生
(1) kill向进程发送实时信号(包含自己)
#include <sys/types.h> #include <signal.h> int kill( pid_t pid, //发送给哪个进程 int sig ); //发送什么信号,见"常见的信号" //參数pid:>0 表示发送给特定的进程 // 0 表示发送给全部和发送信号进程在同一个进程组的进程 // <0 表示发送给abs(pid)相应的进程组中的全部进程 //返回值:0(发送成功)、-1(发送失败,失败信息见errno)
#include <sys/types.h> #include <signal.h> int sigqueue(pid_t pid, //对那个进程发送 int sig, //发送什么信号 const union sigval val); //处理函数中须要携带什么參数? //返回值:成功返回0。错误返回-1
#include <signal.h> int raise(int signo); //返回值:成功返回 0;否则返回 -1
#include <stdlib.h> void abort(void);
#include <unistd.h> unsigned int alarm( unsigned int seconds ); //參数seconds: >0 定时seconds秒之后产生SIG_ALRM信号 // =0 不在产生信号(等于关闭闹钟)
四 信号的捕捉
1 由系统捕捉,程序不做处理,此时会由系统採用默认方法处理。
(1) 没有參数的信号处理
(2) 有參数的信号处理,和一般和sigqueue()配合使用
#include <signal.h>
typedef void(* sighandler_t)(int);
sighandler_t signal(int signal, //信号
sighandler_t handler); //信号相应的处理函数
handler取值:假设对信号不做处理。直接忽略。 取值为 SIG_IGN
假设採用系统默认方式处理信号。
取值为 SIG_DFL
假设,须要运行操作用户自己定义的操作,则取值为用户定义的 函数指针。
#include <signal.h>
int sigaction(int signo, //信号,为除SIGKILL及SIGSTOP外的不论什么一个信号。
const struct sigaction *act, //对信号的处理结构体
struct sigaction *oact); //用来保存原来对对应信号的处理,能够置为NULL
//struct sigaction结构体原型:
struct sigaction
{
void (*sa_handler)(int signo) ; //仅仅有信号值为參数的处理函数
void (*sa_sigaction)(int signu, siginfo_t *info, void *act) ; //能够携带siginfo_t结构体參数的处理函数。act參数保留不用
sigset_t sa_mask; //指定信号处理过程中哪些信号被堵塞,默认是当前正在处理的信号
int sa_flags; //信号处理相关标志位,比方:传递信息的时候置为SA_SIGINFO
void (*sa_restore)(void); //POSIX不在支持,忽略不用
}
//当中,siginfo_t 的原型:
siginfo_t {
int si_signo; /* Signal number */
int si_errno; /* An errno value */
int si_code; /* Signal code */
pid_t si_pid; /* Sending process ID */
uid_t si_uid; /* Real user ID of sending process */
int si_status; /* Exit value or signal */
clock_t si_utime; /* User time consumed */
clock_t si_stime; /* System time consumed */
sigval_t si_value; /* Signal value */
int si_int; /* POSIX.1b signal */
void * si_ptr; /* POSIX.1b signal */
void * si_addr; /* Memory location which caused fault */
int si_band; /* Band event */
int si_fd; /* File descriptor */
}
//sigval就是携带的參数信息,能够是int型也能够是指针。
union sigval
{
int sival_int;
void *sival_ptr;
}
五 使用实例
1 没有參数的信号
/*************************************************************************
> File Name: testsignal.c
> Author: qiaozp
> Mail: qiaozongpeng@163.com
> Created Time: 2014-9-18 17:12:01
> Step: 1 定义信号处理函数
2 绑定信号 和 处理函数
3 发出信号
************************************************************************/
#include <signal.h>
#include<iostream>
using namespace std;
//1 定义信号处理函数
void dealSignal(int signo)
{
cout << "收到不带參数的信号 : " << signo << endl;
return ;
}
int main()
{
//2 绑定信号 和 处理函数
signal(SIGINT, dealSignal);
sleep(3);
//3 发出信号
raise(SIGINT);
return 0;
}
2 有參数的信号
/*************************************************************************
> File Name: testsigaction.c
> Author: qiaozp
> Mail: qiaozongpeng@163.com
> Created Time: 2014-9-18 17:12:01
> Step: 1 定义信号处理函数
2 绑定信号和处理函数
3 发出信号,携带參数
************************************************************************/
#include <signal.h>
#include<iostream>
using namespace std;
//1 定义信号处理函数
void dealSigAction(int signo, siginfo_t* info, void *)
{
cout << "收到带參数的信号 : " << signo << endl;
cout << "參数信息是 : " << info->si_value.sival_int << endl;
return ;
}
int main()
{
struct sigaction sigAction;
sigAction.sa_sigaction = dealSigAction;
sigAction.sa_flags = SA_SIGINFO;//这个是传參的开关。须要设置,否则參数传只是去
//2 绑定信号 和 处理函数
if (sigaction(SIGTSTP, &sigAction, NULL) != 0)
{
cout << "绑定信号处理函数失败" << endl;
}
sleep(3);
union sigval info;
info.sival_int = 10;
//3 发送信号
if (sigqueue(getpid(), SIGTSTP, info) != 0)
{
cout << "发送信号失败" << endl;
}
return 0;
}posted on 2017-06-16 14:22 cynchanpin 阅读(290) 评论(0) 收藏 举报
浙公网安备 33010602011771号