kill函数、raise函数
函数原型
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
kill命令就是调用这个函数来实现。
#include <signal.h>
int raise(int sig);
功能
1)kill:向PID所指向的进程发送指定的信号。
2)raise:向当前进程发送指定信号。
返回值
1)kill:成功返回0,失败返回-1,errno被设置。
2)rasie:成功返回0,失败返回非0。
代码演示:
演示kill函数:
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char **argv, char **environ)
{
kill(getpid(), SIGUSR1);
while(1);
return 0;
}
运行结果为:
演示raise函数:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char **argv, char **environ)
{
raise(SIGKILL);
while(1);
return 0;
}
运行结果为:
我们可以看到提示当前进程是被kill终止。而且arise的动作只能是终止,不能是捕获。
raise函数用的比较少,不过当多个进程协同工作时,kill函数有时还是会用到的。
比如向其它进程发送某信号,通知其某件事情发生了,其它进程收到这个信号后,就会调用信号处理函数进行相应的处理,以实现协同工作。
alarm函数、pause函数
函数原型
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
int pause(void);
功能
alarm函数
设置一个定时时间,当所设置的时间到后,内核会向调用alarm的进程发送SIGALRM信号。SIGALRM的默认处理方式是终止。
pause函数
调用该函数的进程会永久挂起(阻塞或者休眠),直至被信号(任意一个信号)唤醒为止。
返回值
alarm函数:
返回上一次调用alarm时所设置时间的剩余值。
如果之前没有调用过alarm,又或者之前调用alarm所设置的时间早就到了,那么返回的剩余值就是0。
pause函数:
只要一直处于休眠状态,表示pause函数一直是调用成功的。
当被信号唤醒后会返回-1,表示失败了,errno的错误号被设置EINTR(表示函数被信号中断)。
代码演示:
alarm函数:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char **argv, char **environ)
{
alarm(5);
while(1);
return 0;
}
运行结果为:
程序会在5秒钟之后默认终止并且打印:
我们可以对于SIGALRM信号进行捕获:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("time up\n");
}
int main(int argc, char **argv, char **environ)
{
signal(SIGALRM,signal_fun);
alarm(5);
while(1);
return 0;
}
运行结果为:
程序会在5秒之后调用信号捕获函数打印出来time up 然后进入死循环,通过ctrl+c让进程终止。
那么接下来我们接收alarm函数的返回值:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("time up\n");
}
int main(int argc, char **argv, char **environ)
{
unsigned int ret = 0;
signal(SIGALRM,signal_fun);
ret = alarm(5);
printf("ret = %d\n",ret);
while(1);
return 0;
}
运行结果为:
先打印0,5秒之后输出time up 后面我们手动按下ctrl+c
由于是第一次调用alarm函数所以返回值为0
我们换一种情况:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("time up\n");
}
int main(int argc, char **argv, char **environ)
{
unsigned int ret = 0;
signal(SIGALRM,signal_fun);
ret = alarm(5);
sleep(2);
ret = alarm(6);
printf("ret = %d\n",ret);
while(1);
return 0;
}
运行结果为:
先调用alarm设置5秒的定时,然后调用sleep休眠2秒钟之后,那么设置的5秒定时还有3秒没有到,第二次调用alarm会把定时时间修改为6,并且发现上一次定时的时间还没有到就返回上一次剩余的时间。
‘那么如果我们第一次定时的时间进行完之后,第二次调用alarm返回值仍然是0.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("time up\n");
}
int main(int argc, char **argv, char **environ)
{
unsigned int ret = 0;
signal(SIGALRM,signal_fun);
ret = alarm(5);
sleep(6);
ret = alarm(6);
printf("ret = %d\n",ret);
while(1);
return 0;
}
运行结果为:
由于设置的alarm小于sleep中设置的时间,所以第二次调用alarm函数之后返回值为0.
pause函数演示:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
int main(int argc, char **argv, char **environ)
{
pause();
printf("hello\n");
while(1);
return 0;
}
运行结果为:
我们可以看到没有打印出来hello,进程被阻塞,上面程序我们按下ctrl+c之后hello也没有被打印出来,原因就是按下ctrl+c之后虽然进程被唤醒,但是进程被终止了。
那么我们也可以对于信号进行捕获操作:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("SIGINT to signal_fun\n");
}
int main(int argc, char **argv, char **environ)
{
signal(SIGINT,signal_fun);
pause();
printf("hello\n");
while(1);
return 0;
}
运行结果为:
那么按下ctrl+c之后进程被唤醒,执行捕获函数,之后打印hello,然后计入死循环,每次按下ctrl+c的时候都会把进程终止信号通过捕获函数进行操作。
alarm函数用的不多,pause在实际开发中也用的不多,不过在开发中往往会使用pause()函数来帮助调试,比如我想让程序运行到某位置时就停下,然后分析程序的打印数据,此时就是可以关键位置使用pause函数将程序休眠(停下)。不想继续休眠时使用信号唤醒即可。
abort函数
abort函数我们在前面博客中使用过。
调用该函数时,会向当前进程发一个SIGABRT信号,这个信号的默认处理方式是终止,因此如果不忽略和捕获的话,会将当前进程终止掉。
代码演示:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
void signal_fun()
{
printf("time up\n");
}
int main(int argc, char **argv, char **environ)
{
abort();
while(1);
return 0;
}
运行结果为:
我们可以看到进程被终止,并且提示出是被abort信号终止。