目录
一、信号的概念
二、signal()库函数
三、kill()函数
1、函数作用
2、函数原型
四、可靠与不可靠信号
五、总结
一、信号的概念 信号是UNIX系统响应某些状况而产生的事件,进程在接收到信号时会采取相应的行动,信号是因为某些错误条件而产生的,比如内存段冲突、浮点处理器错误或者非法指令等。它们由shell和终端管理器产生以引起中断。信号的目的是为了通知做某件事,就比如早上的闹钟通知你起床,闹钟就起到一个信号的作用。
在linux下可以通过 kill -l 查看所有的信号
文章图片
之前提到过通过 kill -9 进程ID,可以把该ID所属的进程结束掉。学习了信号这个概念,可以将这条命令理解为发送第9个信号给该ID所属的进程,通知他去做某件事。通过上图所示第9个信号为SIGKILL,也就是发送停止进程的信号给该ID所属的进程,通知它停下来,也就是所谓的“杀死”进程。
编号为1-31的为不可靠信号,34-64的为可靠信号。连续不间断发送信号,信号会丢失的为不可靠信号,连续不间断发送信号,信号不会丢失的为可靠信号。
二、signal()库函数 如果想让程序能够处理信号,可以使用 signal库函数,要引入头文件。在linux终端下输入命令 man signal来查看他的函数原型
文章图片
可以看到,signal()函数的第一个参数signum是信号编号,也就是 kill -l 能够查询到的所有信号,第二个参数sighandler是一个函数指针。
准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数由sighandler给出。sighandler这个函数必须有一个int类型的参数(即接收到的信号代码),函数本身的类型是void,sighandler也可以是下面两个特殊值:SIG_IGN(屏蔽该信号),SIG_DFL (恢复默认行为)。
通俗的说signal()库函数的作用是将某个信号和某个函数绑定起来,当这个信号被发送出来,就去做绑定的这个函数的业务。Qt的信号与槽机制就是通过借鉴这种方式来实现的。
三、kill()函数
1、函数作用
kill函数的作用是把参数sig给定的信号发送给标识号为pid的进程。如果该信号通过sinal()和某个函数绑定起来,那么就暂时中断这个进程,去做绑定的这个函数的业务,做完这个函数的业务,进程继续运行。
要想发送一个信号,发送者进程必须拥有相应的权限。这通常意味着两个进程必须拥有同样的用户ID。
2、函数原型
int kill(pid_t pid, int sig);四、可靠与不可靠信号 下面通过一段代码来验证可靠信号和不可靠信号
参数:
pid:进程ID
sig:某个信号
【linux远程开发|linux远程开发——信号的使用(信号绑定和发送)】返回值:
成功返回0,出错返回-1。
#include
#include
#include
#include
#include using namespace std;
void signalfunction(int i);
int main()
{
int pid = 0;
int status = 0;
//将信号和函数绑定在一起
signal(SIGUSR1, signalfunction);
pid = fork();
if (pid == 0)//子进程
{
while(1)
{
cout << "子进程运行中 pid = " << getpid() << endl;
sleep(1);
}
}
else if(pid > 0)//父进程
{
sleep(3);
//先让子进程先处理业务,测试kill函数
for (int i = 1;
i <= 5;
i++)
{
cout << "父进程给子进程发送第 " << i << " 个信号" << endl;
kill(pid, SIGUSR1);
//给子进程发送信号
}
sleep(3);
//延时3秒
kill(pid, SIGKILL);
//给子进程发送停止信号
waitpid(pid, &status, 0);
//等待子进程结束,防止子进程托孤
cout << "子进程结束" << endl;
}
return 0;
}void signalfunction(int i)
{
cout << "函数被调用了 i = " << i << endl;
}
编号为10的信号(SIGUSR1)和编号为12的信号(SIGUSR2)都是用户信号,程序员可以使用他,同时这两个信号都是不可靠信号。
上面的这段代码父进程通过一个for循环循环发送5次信号(SIGUSR1),而该信号(SIGUSR1)通过signal(SIGUSR1, signalfunction)和signalfunction()函数绑定起来,也就是说发送一次信号就会调用一次这个signalfunction()函数。控制台输出如下:
文章图片
可以发现父进程发送了5次信号,可是绑定的函数才执行一次,也就是出现了信号丢失的现象,印证了:连续不间断发送信号,信号会丢失的为不可靠信号,编号为1-31的都是不可靠信号。同时可以发现调用的函数打印的int类型的值正好是该不可靠信号(SIGUSR1)的编号10。
如果将signal(SIGUSR1, signalfunction)改为signal(SIGRTMIN, signalfunction),发送信号kill(pid, SIGUSR1)改为kill(pid, SIGRTMIN)来继续测试,控制台输出如下:
文章图片
可以发现父进程发送了5次信号,绑定的函数也执行了5次,也就是信号并没有丢失,印证了:连续不间断发送信号,信号不会丢失的为可靠信号,编号为34-64的都是可靠信号。调用的函数打印的int类型的值也正好是该可靠信号(SIGRTMIN)的编号34。
五、总结 1、signal()函数可以将某个信号和某个函数绑定起来。
2、kill()函数可以发送某个信号给某个ID的子进程,并暂时中断该子进程,转去处理这个信号通过signal()函数绑定的函数业务。
3、编号为1-31的都是不可靠信号,34-64的都是可靠信号。连续不间断发送信号时不可靠信号会出现信号丢失的现象,而可靠信号不会出现这个现象。
原创不易,转载请标明出处。
对您有帮助的话可以点赞收藏+关注,会持续更新的(嘻嘻)。
推荐阅读
- linux远程开发|linux远程开发——(IPC通信)共享内存的使用
- linux远程开发|linux远程开发——使用vs2019远程连接linux
- linux|Asahi Linux 初版发布,面向所有用户开放下载
- Linux|传输层TCP与UDP
- Linux|Linux编程——网络编程
- Linux|Linux socket编程(C语言socket实现客户端与服务器网络通信)
- linux远程开发|linux远程开发——网络通信(客户端与服务器建立连接)
- Linux之fgrep命令
- OpenWrt|OpenWrt学习总结(2)编译OpenWrt过程中整理的软件包下载网址