例如如果我们想要把一个进程给终止掉,那么我们就可以使用ctrl+c来终止进程,ctrl+c就是一个信号
如何更改处理型号的方式呢?
void handlerSig(int sig)//重新修改处理信号的方式
{
std::cout << "获得了一个信号: " << sig << std::endl;
}
//函数调用
signal(2, handlerSig);//2就是ctrl+c对应的信号,handlersig是函数指针
ctrl+c是直接从键盘上输入的信号,我们也可以自己写一个系统调用–mykill来实现一样的效果
mykill.cc:
#include <iostream>
#include <string>
#include <sys/types.h>
#include <signal.h>
// ./mykill signumber pid
int main(int argc, char *argv[])//编译完成后,bash进程运行指令./mykill 9 1234
{
if(argc != 3)//表示指令个数,:1../mykill 2.9 3.1234--进程pid
{
std::cout << "./mykill signumber pid" << std::endl;
return 1;
}
int signum = std::stoi(argv[1]);//argv【1】存储指令:9
pid_t target = std::stoi(argv[2]);//argv【2】存储指令: 1234--进程pid
//二者都要使用stoi函数转换成征整形!!!!!
int n = kill(target, signum);//调用kill函数,参数是进程pid和信号
if(n == 0)
{
std::cout << "send " << signum << " to " << target << " success.";
}
return 0;
}
testSig.cc:
#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
void handlerSig(int sig)
{
std::cout << "获得了一个信号: " << sig << std::endl;
exit(13);//在编译完运行程序后只要通过键盘输入信号,那么都改成输出,特别注意---⑨是没有办法改的,因为9号是强制杀掉进程,为了避免垃圾程序一直处于运行中,需要保留9号来及时删除程序,绝大部分的信号的原始处理方式都是终止进程
}
int main()
{
for(int i = 1; i < 32; i++)
signal(i, handlerSig);//改写31个普通信号处理机制,这个循环只有在用户输出信号时才运行,无论用户输入什么信号,都会把其改写成输出信号编号,而不使用信号原本的功能
int cnt = 0;
while (true)
{
std::cout << "hello world, " << cnt++ << " ,pid: " << getpid() << std::endl;
sleep(1);
}
}
makefile:
.PHONY:all
all:testsig mykill
testsig:testSig.cc
g++ -o $@ $^ -std=c++11
mykill:mykill.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f testsig mykill
信号异常现象:
#include <stdio.h>#include <signal.h>
void handler(int sig)
{
printf("catch a sig : %d\n", sig);
}
// v1
int main()
{
//signal(SIGFPE, handler); // 会跳8号错误:::8) SIGFPE
sleep(1);
int a = 10;
a/=0;
while(1);
return 0;
}
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{
printf("catch a sig : %d\n", sig);
}
int main()
{
//signal(SIGSEGV, handler);
sleep(1);
int *p = NULL; // p被初始化为空指针(不指向任何有效内存)
*p = 100; // 试图通过空指针写入数据
while(1);
return 0;
}
使用系统调用alarm:
#include <iostream>
#include <unistd.h>
#include <signal.h>
int main()
{
int count = 0;
alarm(1);//运行一秒后给信号,直接终止进程
while(true)
{
std::cout << "count : "
<< count << std::endl;
count++;
}
return 0;
}
运行结果:
Alarm clock
在进程的pcb表中存有如下内容:
default
----即保持指令原来的功能ignore
------即忽略这个指令的功能运行结果就是:
依旧没有停止
因为2号信号被忽略了!!!!部分函数使用: