一起talk C语言例子(第八十五回:C语言实例--使用信号进行进程间通信二)
各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的例子,这一回咱们接着上一回的内容,继续说该例子。闲话休提,言归正转。让我们一起talk c栗子吧!
我们在上一回中举了使用信号进行进程间通信的例子,在该例子中,我们通过终端发出信号,当进程收到该信号后让它执行对信号定义的默认动作。这一回,我们再来举一个使用信号进行进程间通信的例子,不过,我们发送和处理信号的方式和上一回的例子不一样。在接下来的例子中,我们在一个进程中使用kill产生信号,在另外一个进程中接收并且按照自己的方式处理接收到的信号。
在例子中我们使用kill函数给其它进程发送信号,下面是kill函数的原型:
int kill(pid_t pid, int signo);第一个参数pid表示进程的pid,kill函数将把信号发送给pid与其参数相同的进程; 第二个参数表示信号。该参数表示kill函数发送的信号值。 如果kill成功发送信号,那么返回0,否则返回-1.
在例子中我们使用signal函数设置接收到信号后的处理方式,下面是signal函数的原型:
void (*signal(int signo, void (*func) (int))) (int)
大家看着这个函数是不是觉得有点乱?先别慌,我们慢慢对它进行分析。
这个函数名叫signal,它用来配置信号处理函数,通俗点说,它就是为某个信号分配一个信号处理函数。它有两个参数:
一个参数是signo,表示信号值; 另外一个参数是一个名叫func的函数指针,它表示信号处理函数。 也就是说进程接收到signo表示的信号后会使用该函数来处理信号。 参数中的func是一个函数指针,它指向的函数包含一个int类型的参数,表示信号值,该函数返回void。 最后,我们说一下signal函数的返回值,它返回一个函数,该函数就是func指向的信号处理函数。接下来,我们通过具体的代码来说明它们的用法。
#include #include #include void sig_receive(int signo) { printf("received signal :%d \n",signo); } int main() { pid_t pid; int pid_res; int stat_value; pid = fork(); if(pid > 0) { printf("pid: %d -> father process send signal\n",getpid()); kill(pid,sigalrm); //发送信号 } else if(pid == 0) { signal(sigalrm,sig_receive); //配置信号处理函数 printf("pid: %d -> son process receive signal \n",getpid()); } else { printf("create process failed \n"); return 1; } pid_res = wait(&stat_value); if(pid_res > 0) { printf("son process finished: pid = %d \n",pid_res); } return 0; }
从上面的代码中可以看到,我们在父进程中使用kill函数发送信号,然后在子进程中使用signal函数配置信号处理函数,当子进程收到信号后,信号处理函数就会对该信号进行处理。
看官们,正文中就不写代码了,详细的代码放到了我的资源中,大家可以点击这里下载使用。
下面是程序的运行结果,请大家参考:
pid: 3208 -> father process send signal //父进程发送信号 received signal :14 //信号处理函数在处理信号 pid: 3209 -> son process receive signal //子进程收到信号 son process finished: pid = 3209 //子进程结束,父进程也结束
看官们,从程序的结果中可以看出,父进程发出信号后,子进程收到了信号,并且进行了处理。这说明我们通过信号在两个进程之间进行了通信。
看官们,有个小的细节不知道大家有没有发现:程序运行结果中先是执行信号处理函数中的内容,然后才执行子进程中的内容。如果我们把执行的顺序调换一下会有什么现象呢?
把下面这两行代码的执行顺序调换一下,也是说把printf语句放在signal配置语句的前面。
signal(sigalrm,sig_receive); //配置信号处理函数 printf("pid: %d -> son process receive signal \n",getpid());
重新编译并且运行程序后,得到以下运行结果:
pid: 2611 -> father process send signal //父进程发送信号 son process finished: pid = 2612 //子进程结束,父进程也结束
从上面的结果中以可以看到,子进程不但没有收到信号,而且没有执行。这是什么原因呢?那是因为父进程发信号的时候子进程可能被阻塞,所以没有执行。这也是signal函数缺点。
signal函数是早期unix系统提供的函数,现在的新系统中已经使用sigaction函数取代它,不过在一些老的程序中还是能看到它的身影。下一回中,我们将介绍sigcation函数相关的内容。
各位看官,关于使用信号进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。
上一篇: 到底该如何看待谭浩强的“C程序设计”
下一篇: 树中的最长路
推荐阅读
-
一起talk C栗子吧(第一百零一回:C语言实例--使用信号量进行进程间同步与互斥二)
-
一起talk C栗子吧(第一百零二回:C语言实例--使用信号量进行进程间同步与互斥三)
-
一起talk C栗子吧(第八十六回:C语言实例--使用信号进行进程间通信三)
-
一起talk C栗子吧(第九十七回:C语言实例--使用消息队列进行进程间通信一)
-
一起talk C栗子吧(第九十八回:C语言实例--使用消息队列进行进程间通信二)
-
一起talk C栗子吧(第九十六回:C语言实例--使用共享内存进行进程间通信二)
-
一起talk C栗子吧(第八十三回:C语言实例--进程间通信概述)
-
一起talk C语言例子(第八十五回:C语言实例--使用信号进行进程间通信二)
-
一起talk C栗子吧(第一百零一回:C语言实例--使用信号量进行进程间同步与互斥二)
-
一起talk C栗子吧(第一百零二回:C语言实例--使用信号量进行进程间同步与互斥三)