信号相关函数:kill、raise、alarm、pause、abort(信号)【linux】(zt)

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信号终止。

发布了163 篇原创文章 · 获赞 94 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43648751/article/details/104667777
今日推荐