linux系统进程间通信有很多种方式:较多使用的有信号,管道以及System VIPC。各种通信方式各有优缺点。这部分主要就进程间通信方式进行总结。
1 信号。
信号进行进程间通信方式有一点需要明确:信号只能通知,不能在进程间共享数据资源。也就是说信号仅仅是告诉你一下某个事情发生了。而我们的程序则可以对这个信号进行各种我们自定义或者默认的处理,更或者当做没有听见。
那么既然是通知一件事情发生了,那肯定是我们关心的一些事情。计算机不像我们人类,告诉我们事情不能任意的表达,所以告诉我们的事情都有固定的格式。那么我们系统可以告诉我们哪些事情呢?我们可以通过kill -l在系统中查看。
这是我的系统输出 Ubuntu系统内核为4.4.0。目前该系统定义的有64种信号。在编写程序的时候这些信号被定义为整型(正整型)常量并放在<signal.h>头文件中。
从该图中可以看出不存在0信号,该信号在POSIX定义为空信号,系统有特殊的应用。
(并不是所有主机显示的信号都一样,不同的操作系统对信号的定义是不一样的)
上面的信号这里不一一介绍说明,会在后期的学习和编码用例中分别举例说明。
到这里的时候可能会考虑一个问题,信号的种类知道了,那么系统怎么通知我呢?
我们使用signal函数(该函数的定义可以使用man查询)定义我们感兴趣的信号,并对该信号执行我们的处理方式。一般情况下对信号的处理有三种方式SIG_IGN(忽略信号不做任何处理)、SIG_DEF(执行系统自定义的默认操作)、自定义我们的操作函数。下面使用一段代码来看看signal的处理方式。
#include
#include
#include
#include
void sighand(int num)
{
printf("The signum:%d\n",num);
printf("自定义信号处理\n");
}
int main(int argc,char **argv)
{
//signal(SIGINT,SIG_DFL);
//signal(SIGINT,SIG_IGN);
signal(SIGINT,sighand);
while(1)
{
pause();
}
}
不过需要注意一点有两个信号不能忽略:SIGKILL和SIGSTOP。
上面的信号都是系统发送到我们的应用程序的,但是是否可以进程向进程发送信号呢?当然设计者早就想到了这层,使用kill函数,就能达到这样的目的。下面这段代码子进程在5秒后向父进程发送SIGINT信号。(kill不但将信号发给进程还发给该进程组)
#include
#include
#include
#include
void sighand(int num)
{
printf("收到子进程发来的信号:%d\n",num);
}
int main()
{
pid_t pid;
pid_t fad=getpid();
signal(SIGINT,sighand);
if((pid==fork())==0)
{
sleep(5);
kill(fad,SIGINT);
return 0;
}
while(1)
{
pause();
}
return 0;
}
目前信号处理就写到这里,但是信号处理还有一些需要扩充,这个在后期的学习中更加深入的学习和扩展。()
(后期更新……)