Linux网络编程【信号】2
【摘要】 07. 信号产生函数 7.1 kill函数#include <sys/types.h>#include <signal.h>int kill(pid_t pid, int sig);功能:给指定进程发送指定信号(不一定杀死)参数: pid : 取值有 4 种情况 : pid > 0: 将信号传送给进程 ID 为pid的进程。 pid = 0 : 将信号...
07. 信号产生函数
7.1 kill函数
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
功能:给指定进程发送指定信号(不一定杀死)
参数:
pid : 取值有 4 种情况 :
pid > 0: 将信号传送给进程 ID 为pid的进程。
pid = 0 : 将信号传送给当前进程所在进程组中的所有进程。
pid = -1 : 将信号传送给系统内所有的进程。
pid < -1 : 将信号传给指定进程组的所有进程。这个进程组号等于 pid 的绝对值。
sig : 信号的编号,这里可以填数字编号,也可以填信号的宏定义,可以通过命令 kill - l("l" 为字母)进行相应查看。不推荐直接使用数字,应使用宏名,因为不同操作系统信号编号可能不同,但名称一致。
返回值:
成功:0
失败:-1
super用户(root)可以发送信号给任意用户,普通用户是不能向系统用户发送信号的。
kill -9 (root用户的pid) 是不可以的。同样,普通用户也不能向其他普通用户发送信号,终止其进程。 只能向自己创建的进程发送信号。
普通用户基本规则是:发送者实际或有效用户ID == 接收者实际或有效用户ID
程序示例:
pid_t pid = -1;
//创建子进程
pid = fork();
if(pid == -1){perror("fork");return 1;}
if(pid == 0)
{
//子进程
for(int i=0; i<5; i++)
{
printf("chile process do work...\n");
sleep(1);
}
exit(0);//进程的退出
}
else
{
//父进程
sleep(3);
printf("子进程还在运行,该退出了\n");
kill(pid,15);
printf("父进程kill子进程完毕!\n");
}
return 0;
运行结果:
如果子进程想自杀,好;
kill(getpid(),15);
,要是看父进程不爽就kill("getppid()",15);
7.2 raise函数
#include <signal.h>
int raise(int sig);
功能:给当前进程发送指定信号(自己给自己发),等价于 kill(getpid(), sig)
参数:
sig:信号编号
返回值:
成功:0
失败:非0值
示例代码:
int i = 1;
while(1)
{
printf("do working %d\n",i);
//自己给自己发送一个信号
if(i == 4)
{
raise(SIGTERM);//等价于kill(getpid(),15);
}
i++;
sleep(1);
}
return 0;
运行结果:
7.3 abort函数
#include <stdlib.h>
void abort(void);
功能:给自己发送异常终止信号 6) SIGABRT,并产生core文件,等价于kill(getpid(), SIGABRT);
参数:无
返回值:无
7.4 alarm函数(闹钟)
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
功能:
设置定时器(闹钟)。在指定seconds后,内核会给当前进程发送14)SIGALRM信号。进程收到该信号,默认动作终止。每个进程都有且只有唯一的一个定时器。
取消定时器alarm(0),返回旧闹钟余下秒数。
参数:
seconds:指定的时间,以秒为单位
返回值:
返回0或剩余的秒数
定时,与进程状态无关(自然定时法)!就绪、运行、挂起(阻塞、暂停)、终止、僵尸……无论进程处于何种状态,alarm都计时。
测试程序:
//测试alarm函数
int main()
{
unsigned int ret = 0;
//第一次设置脑中5秒之后就超时,发送对应的信号
ret = alarm(5);
printf("上一次闹钟剩下的时间是:%u\n",ret);
sleep(2);
//之前没有超时的闹钟被新闹钟覆盖
ret = alarm(4);
printf("上一次闹钟剩下的时间是:%u\n",ret);
printf("按任意键继续...\n");
getchar();
return 0;
}
运行结果:
xcc@ubuntu:~/7th$ ./a.out
上一次闹钟剩下的时间是:0
上一次闹钟剩下的时间是:3
按任意键继续…
闹钟
xcc@ubuntu:~/7th$ ./a.out
上一次闹钟剩下的时间是:0上一次闹钟剩下的时间是:3
按任意键继续…
7.5 setitimer函数(定时器)
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
功能:
设置定时器(闹钟)。 可代替alarm函数。精度微秒us,可以实现周期定时。
参数:
which:指定定时方式
a) 自然定时:ITIMER_REAL → 14)SIGALRM计算自然时间
b) 虚拟空间计时(用户空间):ITIMER_VIRTUAL → 26)SIGVTALRM 只计算进程占用cpu的时间
c) 运行时计时(用户 + 内核):ITIMER_PROF → 27)SIGPROF计算占用cpu及执行系统调用的时间
new_value:struct itimerval, 负责设定timeout时间
struct itimerval {
struct timerval it_interval; // 闹钟触发周期
struct timerval it_value; // 闹钟触发时间
};
struct timeval {
long tv_sec; // 秒
long tv_usec; // 微秒
}
itimerval.it_value: 设定第一次执行function所延迟的秒数
itimerval.it_interval: 设定以后每几秒执行function
old_value: 存放旧的timeout值,一般指定为NULL
返回值:
成功:0
失败:-1
示例代码:
void myfunc(int sig)
{
printf("捕捉到信号:%d\n",sig);//14
}
int main()
{
struct itimerval new_value;
//定时周期
new_value.it_interval.tv_sec = 1;
new_value.it_interval.tv_usec = 0;
//第一次触发的时间
new_value.it_value.tv_sec = 2;
new_value.it_value.tv_usec = 0;
signal(SIGALRM, myfunc); //信号处理
setitimer(ITIMER_REAL, &new_value, NULL); //定时器设置
//进程收到闹钟超时信号之后就会终止该进程
while (1);
return 0;
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)