一、信号
信号是在软件层次上对中断机制的一种模拟。在原来上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的:一个进程不必通过任何操作来等待信号的到达。信号可以之间进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间发生了哪些系统事件。它可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行态,则该信号由内核保存起来,直到该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程。
如下命令查看信号及其编号:
进程可以通过三种方式来响应一个信号:
1.忽略信号:即对信号不做任何处理,其中,有两个信号不能被忽略:SIGKILL及SIGSTOP
2.捕捉信号:定义信号处理函数,当信号发生时,执行相应的处理函数
3.执行默认操作:Linux对每种命令都规定了默认操作
二、主要函数
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
——————————————————————————————————————————————————————
#include <signal.h>
int raise(int sig);
——————————————————————————————————————————————————————
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
——————————————————————————————————————————————————————
#include <unistd.h>
int pause(void);
——————————————————————————————————————————————————————
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
______________________________________________________
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
三、实例
1.信号发送:kill()和raise()
/*########################################################################
# File Name: kill.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时34分32秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>
int main(int argc,char **argv){
if(ERRVAL == kill(getpid(), SIGKILL)) handle_error("kill");
return 0;
}
/*########################################################################
# File Name: raise.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时40分49秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)
#include<signal.h>
int main(int argc,char **argv){
if(0 != raise(3)) handle_error("raise");
return 0;
}
2.定时器信号:alarm()和pause()
/*########################################################################
# File Name: alarm_pause.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时42分54秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)
#include<unistd.h>
#include<signal.h>
#include<sys/time.h>
#define DELAY_TIME 5
int count = 0;
/*
void setitimer_out(){
printf("%d\n", count++);
}
*/
int main(int argc,char **argv){
#if 0
struct sigaction act;
act.sa_handler = setitimer_out;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF, &act, NULL);
struct itimerval val;
val.it_value.tv_sec = 1;
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_PROF, &val, NULL);
while(1);
#endif
printf("alarm_retval = %d\n", alarm(DELAY_TIME));
printf("alarm_retval = %d\n", 2*alarm(DELAY_TIME));
printf("alarm_retval = %d\n", 3*alarm(DELAY_TIME));
if(ERRVAL == pause()) handle_error("pause");
return 0;
}
定时器alarm只能设定一个,后面设定的alarm返回值为该函数的剩余时间
3.信号的设置:signal()和sigaction()
/*########################################################################
# File Name: sig_parent.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 16时57分37秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#include<unistd.h>
#include<signal.h>
#include<sys/types.h>
#include<sys/wait.h>
void sighandler_t(int signum);
int main(int argc,char **argv){
pid_t pid;
if(ERRVAL == (pid = fork()))handle_error("fork");
if(0 == pid){
sleep(2);
exit(EXIT_SUCCESS);
}
else{
int *status;
signal(SIGCHLD, sighandler_t);
wait(status);
}
return 0;
}
void sighandler_t(int signum){
while(1){
printf("child exit-----\n");
sleep(1);
}
}
/*########################################################################
# File Name: alarm_pause.c
# Author: tanyaduckal
# mail: 2295375354@qq.com
# Created Time: 2022年01月04日 星期二 22时42分54秒
########################################################################*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define CORVAL 1
#define NORVAL 0
#define ERRVAL -1
#define _STR(x) _VAL(x)
#define _VAL(x) #x
#define handle_error(LOG) do { perror(LOG); exit(EXIT_FAILURE); } while(0)
#define qDbug() do { puts(_STR(__LINE__)); } while(0)
#include<unistd.h>
#include<signal.h>
#include<sys/time.h>
#define DELAY_TIME 5
int count = 0;
void setitimer_out(){
printf("%d\n", count++);
}
int main(int argc,char **argv){
struct sigaction act;
act.sa_handler = setitimer_out;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF, &act, NULL);
struct itimerval val;
val.it_value.tv_sec = 1;
val.it_value.tv_usec = 0;
val.it_interval = val.it_value;
setitimer(ITIMER_PROF, &val, NULL);
while(1);
// printf("alarm_retval = %d\n", alarm(DELAY_TIME));
// printf("alarm_retval = %d\n", 2*alarm(DELAY_TIME));
// printf("alarm_retval = %d\n", 3*alarm(DELAY_TIME));
// if(ERRVAL == pause()) handle_error("pause");
return 0;
}
sigaction可以为特定的信号设置处理函数,并且可以保存上一次的处理方式