开篇先说一句,这是信号!!!!!不是信号量
进程间的通信可以分为一下几类:
1、信号
2、管道
3、共享内存
4、消息队列
5、信号量集
6、网络编程
以上后续我都会一个一个更哦!
第一节我们先讲信号:
1、信号的本质?
信号就类似中断,当中断源被触发就去执行中断服务函数。这样说好理解吧!再通俗点说,信号就像马路上的红绿灯,红灯亮起时候,不允许车通过,当绿灯亮起时候车辆可以通行。
2、信号的分类?
按照可靠性方面: 可靠信号 不可靠信号
与时间关系分类: 实时信号 非实时信号
3、信号的处理方式?
3种:默认 忽略 捕捉
我们来看一下在系统中一共有多少种信号:62种
可使用kill -l
命令查看。
注意没有32,33这两个信号。一共62种
前1~31 不可靠信号 信号可能丢失
后34~64 可靠信号 支持排队 不会丢失 实时信号
接下来我们先看两个函数:
int kill(pid_t pid, int signum)
作用:给一个指定进程发送信号量
参数:
pid:> 0:发送信号给指定进程
pid= 0:发送信号给跟调用kill函数的那个进程处于同一进程组的进程。
pid< -1: 取绝对值,发送信号给该绝对值所对应的进程组的所有组员。
pid= -1:发送信号给,有权限发送的所有进程。
signum:待发送的信号类型62种其中的
返回值:成功: 0
失败: -1
signal(int signum, sighandler_t handler)
作用:设置某个信号量的动作,默认、忽略、捕捉
参数:
signum:我们要选择的那个信号量(62种信号量其中的)
handler:设置信号量的动作
主要有三种:
如果handler是SIG_IGN,表示忽略类型为参数signum的信号;
如果handler是SIG_DFL,表示类型为参数signum行为恢复为默认行为;
还有一种就是用户自定义的,可写自定义的函数。
接下来我们来进行实战演练:
首先是kill函数的演练:
我们先写一个简单的程序
main.c程序
#include <stdio.h>
int main()
{
printf("pid=%d\n", getpid());
while(1);
}
可以看到我让程序打印完当前的进程号后就卡死在while循环里面了
kill.c程序
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
int main(int argc,char *argv[])
{
pid_t pid=atoi(argv[1]);
int sig=atoi(argv[2]);
kill(pid,sig);
perror("kill");
return 0;
}
//ps:atoi()函数是将字符串类型转换为int类型,比如“123”转换成123
这个程序就是通过kill函数像进程号为pid的进程发送信号为sig的信号。
编译:
gcc main.c -o main
gcc kill.c -o k
运行mian
接下来我们执行kill程序,发送9信号。
这62个信号含义百度都有的,这里就不说了。9就是杀死指定进程的信号。
接下来我们看一下设置信号,即对信号经行设置
mian.c:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
int main()
{
printf("pid=%d\n", getpid());
signal(2,SIG_IGN);//忽略
while(1);
}
kill.c不变
注意:2) SIGINT 也是结束信号,与ctrl+c有关联
可以看到我们发送2信号并没有让进程结束,ctrl+c也无法结束,接下来我们发送9信号
这就是signal函数里面第二个参数选择忽略
接下来我们看看默认
main.c函数
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
int main()
{
printf("pid=%d\n", getpid());
signal(2,SIG_DFL);//默认
while(1);
}
kill.c函数不变
看2信号然它结束了吧
下面是最后一个自定义
main.c函数:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
void signal_handle(int num)
{
printf("%s %d\n",__FUNCTION__,num);
}
int main()
{
printf("pid=%d\n", getpid());
signal(2,signal_handle); //捕捉 自定义
while(1);
}
kill.c函数任然不需要改变
看,当它接收到2信号时就运行了signal_handle函数。就不是默认结束功能了,就没有结束了这个进程了吧!
ps:__FUNCTION__意思是当前函数名,前后是俩个英文格式下划线
如有错误和疑问欢迎评论区或者私信交流!