信号
特点
1、简单
2、 携带的信息量少
3、 使用在某个特定的场景中
信号的状态
1、 产生
2、未决状态 - 没有被处理
3、 递达 - 信号被处理了
相关函数
kill – 发送信号给指定进程
函数原型: int kill(pid_t pid, int sig);
raise – 自己给自己发信号
kill(getpid(), sigkill);
函数原型: int raise(int sig);
§ 返回值:
异常终止信号
函数原型: void abort(void);
没有参数没有返回值, 永远不会调用失败
闹钟(定时器)
alarm -- 设置定时器(每个进程只有一个定时器)
使用的是自然定时法
不受进程状态的影响
函数原型:unsigned int alarm(unsigned int seconds);
参数: 秒
当时间到达之后, 函数发出一个信号:SIGALRM
setitimer – 定时器, 并实现周期性定时
函数原型:
int setitimer(int which,
const struct itimerval *new_value,
struct itimerval *old_value // NULL
);
struct itimerval {
struct timeval it_interval; // 定时器循环周期
struct timeval it_value; // 第一次触发定时器的时间
};
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
相关函数简单测试举例
kill函数使用
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
int main(int argc, const char* argv[])
{
pid_t pid = fork();
if(pid == -1)
{
perror("fork error");
exit(1);
}
if(pid > 0)
{
while(1)
{
printf("parent process pid = %d\n", getpid());
sleep(1);
}
}
else if(pid == 0)
{
sleep(2);
// 弑父
kill(getppid(), SIGKILL);
}
return 0;
}
测试结果
关键代码分析
父进程处于死循环状态,子进程2S后使用kill函数杀死自己的父亲,整个程序最终终止。
raise函数使用
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
int main(int argc, const char* argv[])
{
pid_t pid = fork();
if(pid > 0)
{
// parent
int s;
wait(&s);
if(WIFSIGNALED(s))
{
printf("term by signal: %d\n", WTERMSIG(s));
}
}
else if(pid == 0)
{
raise(SIGINT);
// abort();
}
return 0;
}