👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍
目录
一、通过终端按键产生信号
1.1 Ctrl + /
在上篇博客中(点击跳转),我们已经验证了Ctrl + c
是向前台进程发送2
号信号SIGINT
来中断程序。
这篇再介绍一个组合键:Ctrl + \
。它其实是向前台进程发送3
号信号SIGQUIT
来终止程序,同时会产生一个core
文件。我们可以使用捕捉信号函数signal
来验证。
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;
void myhandler(int signum)
{
// 修改的行为:打印信号编号后退出
cout << "信号编号为:" << signum << endl;
exit(1);
}
int main()
{
// 捕捉3号信号
signal(SIGQUIT, myhandler);
while (true)
{
cout << "我是一个进程,我在做死循环操作" << endl;
sleep(1);
}
return 0;
}
【程序结果】
其原理再简单重复一遍:当按下ctrl + \
,操作系统识别到键盘上有数据,触发了硬件中断,CPU
收到中断请求后,会暂停当前执行的程序,保存当前状态,并根据中断号来调用对应硬件的方法。由于操作系统识别到是特殊控制字符,就将其转化为3
号信号发送给前台进程
1.2 Ctrl + z
Ctrl + z
会向前台进程发送19
号信号SIGSTOP
。当进程收到此信号时,它会立即停止运行。
#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;
int main()
{
while (true)
{
cout << "我是一个进程,我在做死循环操作" << endl;
sleep(1);
}
return 0;
}
【程序结果】
需要注意的是:19
号信号SIGSTOP
不能使用signal
函数捕捉。类似地,9
号信号SIGKILL
用于立即终止一个进程,并且也不能被signal
函数捕捉。
二、通过kill命令产生信号
kill -n <pid>
# n是信号编号
以以下代码为例:
#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{
while (true)
{
cout << "进程:" << getpid() << ", 我在做死循环啦~" << endl;
sleep(1);
}
return 0;
}
【程序结果】
三、通过系统调用接口产生信号
3.1 kill
系统调用kill
函数是用于向进程发送某种信号,其函数原型如下:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
参数解释:
pid
:要发送信号的进程pid
sig
:要发送的信号编号,可以是标准信号如SIGINT
、SIGKILL
,也可以是用户自定义的信号。- 返回值:成功时,返回
0
;失败时,返回-1
,并设置errno
来指示错误的原因。
我们可以使用这个kill
系统调用接口来模拟实现一个kill
命令。首先kill
命令必须是如下形式:
kill -信号编号 进程pid
那么这里就可以巧用main
函数的参数。main
函数的第一个参数argc
:表示字符指针数组当中的有效元素个数。argv
:是一个字符指针数组(向量表),数组以NULL指针结尾,注意argv
的第一个值原因是程序名。
因此,代码如下:
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <signal.h>
#include <sys/types.h>
using namespace std;
void Usage(string proc)
{
cout << "格式:\n\t" << proc << " signum pid\n\n";
}
// argv:程序名argv[0]、信号编号argv[1]、进程pid argv[2]
int main(int argc, char *argv[])
{
// 如果是三个参数,可以杀掉用户指定进程
if