kill,raise,abort
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
- 功能:给任何的进程或者进程组pid, 发送任何的信号 sig
- 参数:
- pid :需要发送的进程的id
> 0 : 将信号发送给指定的进程
= 0 : 将信号发送给当前的进程组
= -1 : 将信号发送给每一个有权限接收这个信号的进程
< -1 : 这个pid=某个进程组的ID取反 (-12345)
- sig : 需要发送的信号的编号或者是宏值,0表示不发送任何信号
kill(getppid(), 9);
kill(getpid(), 9);
int raise(int sig);
- 功能:给当前进程发送信号
- 参数:
- sig : 要发送的信号
- 返回值:
- 成功 0
- 失败 非0
kill(getpid(), sig);
void abort(void);
- 功能: 发送SIGABRT信号给当前的进程,杀死当前进程
kill(getpid(), SIGABRT);
*/
#include<stdio.h>
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>
int main(){
pid_t pid = fork();
if(pid == 0){
//子进程
int i = 0;
for(i = 0; i < 5; i++){
printf("child process\n");
sleep(1);
}
}else if(pid > 0){
//父进程
printf("parent process\n");
sleep(2);
printf("kill child process now\n");
kill(pid, SIGINT);
}
}
alarm
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
- 功能:设置定时器(闹钟)。函数调用,开始倒计时,当倒计时为0的时候,
函数会给当前的进程发送一个信号:SIGALARM
- 参数:
seconds: 倒计时的时长,单位:秒。如果参数为0,定时器无效(不进行倒计时,不发信号)。
取消一个定时器,通过alarm(0)。
- 返回值:
- 之前没有定时器,返回0
- 之前有定时器,返回之前的定时器剩余的时间
- SIGALARM :默认终止当前的进程,每一个进程都有且只有唯一的一个定时器(信号捕捉函数可以捕捉这个信号后做其他操作)。
alarm(10); -> 返回0
过了1秒
alarm(5); -> 返回9
alarm(100) -> 该函数是不阻塞的
*/
#include<stdio.h>
#include<unistd.h>
int main(){
int seconds = alarm(5);
printf("seconds = %d\n", seconds);
sleep(2);
seconds = alarm(2);
printf("seconds = %d\n", seconds);
while(1){
}
return 0;
}
1秒钟电脑能数多少个数?(alarm)
#include <stdio.h>
#include <unistd.h>
实际的时间 = 内核时间 + 用户时间 + 消耗的时间
进行文件IO操作的时候比较浪费时间
定时器,与进程的状态无关(自然定时法)。无论进程处于什么状态,alarm都会计时。
*/
int main() {
alarm(1);
int i = 0;
while(1) {
printf("%i\n", i++);
}
return 0;
}
setitimer:设置一个定时器,可以设置,xx秒后,每xx秒就执行一次,但是紧接着下面的代码未能实现循环的效果,需要用到后面的捕捉函数signal才能实现
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value,
struct itimerval *old_value);
- 功能:设置定时器(闹钟)。可以替代alarm函数。精度微妙us,可以实现周期性定时
- 参数:
- which : 定时器以什么时间计时
ITIMER_REAL: 真实时间,时间到达,发送 SIGALRM 常用
ITIMER_VIRTUAL: 用户时间,时间到达,发送 SIGVTALRM
ITIMER_PROF: 以该进程在用户态和内核态下所消耗的时间来计算,时间到达,发送 SIGPROF
- new_value: 设置定时器的属性
struct itimerval { // 定时器的结构体
struct timeval it_interval; // 每个阶段的时间,间隔时间
struct timeval it_value; // 延迟多长时间执行定时器
};
struct timeval { // 时间的结构体
time_t tv_sec; // 秒数
suseconds_t tv_usec; // 微秒
};
过 10秒 后,每隔 2秒 定时一次
it_value it_interval
- old_value :记录上一次的定时的时间参数,一般不使用,指定NULL
- 返回值:
成功 0
失败 -1 并设置错误号
*/
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
//过3秒以后,每隔2秒定是一次
int main(){
struct itimerval new_value;
//设置间隔时间
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_usec = 0;
//设置延迟的时间,3s之后开始第一次定时
new_value.it_value.tv_sec = 3;
new_value.it_value.tv_usec = 0;
int ret = setitimer(ITIMER_REAL, &new_value, NULL);//非阻塞的
printf("定时器开始了...");
if(ret == -1){
perror("setitime");
exit(0);
}
getchar();
return 0;
}
signal信号捕捉函数:实现循环执行某事件
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 功能:设置某个信号的捕捉行为
- 参数:
- signum: 要捕捉的信号
- handler: 捕捉到信号要如何处理
- SIG_IGN : 忽略信号
- SIG_DFL : 使用信号默认的行为
- 回调函数 : 这个函数是内核调用,程序员只负责写,捕捉到信号后如何去处理信号。
回调函数:
- 需要程序员实现,提前准备好的,函数的类型根据实际需求,看函数指针的定义
- 不是程序员调用,而是当信号产生,由内核调用
- 函数指针是实现回调的手段,函数实现之后,将函数名放到函数指针的位置就可以了。
- 返回值:
成功,返回上一次注册的信号处理函数的地址。第一次调用返回NULL
失败,返回SIG_ERR,设置错误号
SIGKILL SIGSTOP不能被捕捉,不能被忽略。
*/
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void myalarm(int num){
printf("捕捉到的信号的编号是 : %d\n", num);
printf("xxxx\n");
}
//过3秒以后,每隔2秒定是一次
int main(){
//注册信号捕捉,
//signal(SIGALRM, SIG_IGN);//啥也不做了
//signal(SIGALRM, SIG_DFL);//执行默认操作,也就是结束程序
//void (*sighandler_t)(int); 函数指针, int类型的参数,表示捕捉到的信号的值。
signal(SIGALRM, myalarm);
struct itimerval new_value;
//设置间隔时间
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_usec = 0;
//设置延迟的时间,3s之后开始第一次定时
new_value.it_value.tv_sec = 3;
new_value.it_value.tv_usec = 0;
int ret = setitimer(ITIMER_REAL, &new_value, NULL);//非阻塞的
printf("定时器开始了...\n");
if(ret == -1){
perror("setitime");
exit(0);
}
getchar();
return 0;
}
sigaction信号捕捉函数:实现循环执行某事件(和signal效果一样,但是建议使用这个,平台兼容性更好)
#include <signal.h>
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
- 功能:检查或者改变信号的处理。信号捕捉
- 参数:
- signum : 需要捕捉的信号的编号或者宏值(信号的名称)
- act :捕捉到信号之后的处理动作
- oldact : 上一次对信号捕捉相关的设置,一般不使用,传递NULL
- 返回值:
成功 0
失败 -1
struct sigaction {
// 函数指针,指向的函数就是信号捕捉到之后的处理函数
void (*sa_handler)(int);
// 不常用
void (*sa_sigaction)(int, siginfo_t *, void *);
// 临时阻塞信号集,在信号捕捉函数执行过程中,临时阻塞某些信号。
sigset_t sa_mask;
// 使用哪一个信号处理对捕捉到的信号进行处理
// 这个值可以是0,表示使用sa_handler,也可以是SA_SIGINFO表示使用sa_sigaction
int sa_flags;
// 被废弃掉了
void (*sa_restorer)(void);
};
*/
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
void myalarm(int num){
printf("捕捉到的信号的编号是 : %d\n", num);
printf("xxxx\n");
}
//过3秒以后,每隔2秒定是一次
int main(){
struct sigaction act;
act.sa_flags = 0;
act.sa_handler = myalarm;
sigemptyset(&act.sa_mask); //清空临时阻塞信号集
//注册信号捕捉,
sigaction(SIGALRM, &act, NULL);
struct itimerval new_value;
//设置间隔时间
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_usec = 0;
//设置延迟的时间,3s之后开始第一次定时
new_value.it_value.tv_sec = 3;
new_value.it_value.tv_usec = 0;
int ret = setitimer(ITIMER_REAL, &new_value, NULL);//非阻塞的
printf("定时器开始了...\n");
if(ret == -1){
perror("setitime");
exit(0);
}
while (1)
{
}
return 0;
}