信号的机制
进程A给进程B发送信号,进程B收到信号之前执行自己的代码,收到信号后,不管执行到程序的什么位置,都要暂停运行,去处理信号。处理完毕以后再继续执行,与硬件中断类似(软中断),每个进程收到的所有信号,都是由内湖负责发送的。
信号的处理方式
- 执行默认动作
- 忽略信号(丢弃不处理)
- 捕捉信号(调用用户的自定义的处理函数)
信号相关函数
signal函数:
- 作用:注册信号捕捉(处理)函数
- 函数原型
- typedef void(*sighandler t)(int);
- sighandler_t signal(int signum,sighandler_t handler);
- 函数参数
- signum:信号编号
- handler:信号处理函数
- 信号四要素:(man)
- 编号
- 名字
- 默认处理动作
- 信号是如何产生的
给一个没有读端的管道写数据,会产生SIGPIPE信号。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<unistd.h> 6 #include<sys/wait.h> 7 8 //信号处理函数 9 void sighandler(int signo){ 10 printf("signo==[%d]\n",signo); 11 } 12 13 14 int main() 15 { 16 //创建管道 17 //int pipe(int pipefd[2]) 18 int fd[2]; 19 int ret = pipe(fd); 20 if(ret<0) 21 { 22 perror("pipe error"); 23 return -1; 24 } 25 26 //注册SIGPIPE信号处理函数 27 signal(SIGPIPE,sighandler); 28 29 //关闭读端 30 closed(fd[0]); 31 32 write(fd[1],"hello world",strlen("hello world")); 33 34 return 0; 35 }
讯享网
kill函数/命令
- 描述:给指定进程发送指定信号
- kill命令:kill -SIGKILL 进程PID
- kill函数原型:int kill(pid_t pid,int sig);
- 返回值: 成功:0,失败 -1
- 函数参数
- sig信号参数:不推荐直接使用数字,应使用宏名,因为不同操作系统信号编号可能不同,但名称一致。
- pid参数:
- pid>0:发送信号给指定的进程(基本只用这一个)
- pid=0:发送信号给与调用kill函数进程属于同一进程组的所有进程
- pid<-1:取|pid|发给对应进程组
- pid=-1:发送给进程有权限发送的系统中所有进程。
abort函数raise函数:
- raise函数
- 函数描述:当前进程给自己发送信号
- 函数原型:int raise(int sig);
- 返回值:0成功。失败非0
- 函数拓展:raise(signo) == kill(getpid(),signo);
- abort函数
- 函数描述:给自己发送终止信号,6)SIGABRT 并产生core文件
- 函数原型:void abort(void);
- 函数拓展:abort() = kill(getpid(),SIGABRT);
alam函数
- 函数原型:unsigned int alarm(unsigned int seconds);
- 函数描述:设置定时器。在指定seconds后,内核会给当前进程发送(14)SIGALRM信号。进程收到该信号,默认动作为终止。每个进程有且都有唯一的一个定时器
- 函数返回值:返回0或剩余的秒数,无失败。

- 常用操作:取消定时器alarm(0),返回旧闹钟余下秒数。
alarm使用的是自然定时法,与进程状态无关,就绪、运行、挂起(阻塞、暂停)、终止、僵尸...无论进程处于何种状态,alarm都计时。
讯享网 //测试alarm函数。 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<unistd.h> 6 #include<signal.h> 7 8 9 void sighandler(int signo){ 10 printf("signo==[%d]\n",signo); 11 } 12 13 int main() 14 { 15 16 signal(SIGALRM,sighandler); 17 18 int n =alarm(5); 19 printf("n==[%d]\n",n); 20 21 sleep(2); 22 n = alarm(1); 23 printf("n==[%d]\n",n); 24 sleep(10); 25 26 return 0; 27 28 }
测试电脑1秒钟能写多少个数
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<unistd.h> 6 #include<signal.h> 7 8 int main() 9 { 10 alarm(1); 11 int i =0; 12 while(1) 13 { 14 printf("[%d] ",i++); 15 } 16 return 0; 17 } ~

setitimer函数
- 函数原型
- 函数描述
- 函数返回值
- 成功:0;
- 失败:-1,设置errno值
- 函数参数:
- which:指定定时方式
- 自然定时:ITIMER_REAL → 14)SIGALRM计算自然时间
- 虚拟空间计时(用户空间):ITIMER_VIRTUAL → 26)SIGVTALRM 只计算进程占用cpu的时间
- 运行时计时(用户+内核):ITIMER_PROF → 27)SIGPROF计算占用cpu及执行系统调用的时间
- new_value:struct itimerval, 负责设定timeout时间。
- itimerval.it_value: 设定第一次执行function所延迟的秒数
- itimerval.it_interval: 设定以后每几秒执行function
- which:指定定时方式
- old_value: 存放旧的timeout值,一般指定为NULL
- struct itimerval {

struct timerval it_interval; // 闹钟触发周期
struct timerval it_value; // 闹钟触发时间
};
struct timeval {
long tv_sec; // 秒
long tv_usec; // 微秒
}
setitimer练习
讯享网 //setitimer练习 1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<sys/types.h> 5 #include<unistd.h> 6 #include<signal.h> 7 #include<sys/time.h> 8 9 void sighandler(int signo) 10 { 11 printf("signo==[%d]\n",signo); 12 } 13 14 int main() 15 { 16 17 //注册SIGALRM信号处理函数 18 signal(SIGALRM,sighandler); 19 20 struct itimerval tm; 21 //周期性时间赋值 22 tm.it_interval.tv_sec = 1; 23 tm.it_interval.tv_usec = 0; 24 //第一次触发的时间 25 tm.it_value.tv_sec =3; 26 tm.it_value.tv_usec = 0; 27 28 setitimer(ITIMER_REAL,&tm,NULL); 29 30 31 while(1) 32 { 33 sleep(1); 34 } 35 return 0; 36 } ~ ~


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/65755.html