今天同学给了我一个程序,让我解释一些执行诡异的结果,拿过程序我感觉非常简单,但是一运行,结果居然和我所想的不一样,在linux下做编程也不是一天两天了,有几分失落的情况下更感觉自己的无知,深入分析了一下,终于找出了最终的原因!写在这里用以警戒自己,如果有人有兴趣也可以自己跑跑,感觉很不错的一个程序!
程序代码如下:
#include
#include
#include
void sigusr1(int sig)
{
printf("get signal\n");
}
int main()
{
int pid;
int ppid;
if( signal( SIGRTMIN, sigusr1 ) == SIG_ERR ){
perror( "Can not catch SIGRTMIN!" );
}
if( (pid=fork()) == -1 )
perror("fork error!");
else if( pid == 0 ) /*child deal*/
{
sleep(1);
ppid = getppid();
kill( ppid, SIGRTMIN );
}
if( (pid=fork()) == -1 )
perror("fork");
else if( pid == 0 ) /*child deal*/
{
ppid = getppid();
kill( ppid, SIGRTMIN );
sleep(2);
}
sleep(3);
return 0;
}
可以看一下,你认为get signal应该打印出几次?一种很直接的感觉就是两个子进程,应该是执行两次。
错,可以运行一下,是三次!
为什么呢……
呵呵,继续分析一下,在两个子进程创建之后分别添加两条打印不同字符串的语句,比如下面的改法:
int main()
{
int pid;
int ppid;
if( signal( SIGRTMIN, sigusr1 ) == SIG_ERR ){
perror( "Can not catch SIGRTMIN!" );
}
if( (pid=fork()) == -1 )
perror("fork error!");
else if( pid == 0 ) /*child deal*/
{
sleep(1);
ppid = getppid();
kill( ppid, SIGRTMIN );
}
printf("aa\n");
if( (pid=fork()) == -1 )
perror("fork");
else if( pid == 0 ) /*child deal*/
{
ppid = getppid();
kill( ppid, SIGRTMIN );
sleep(2);
}
sleep(3);
printf("bb\n");
return 0;
}
执行一下,你会发现aa打印了2次,而bb出现了4次,有没有什么新的想法或者顿悟?
如果还没有,那我告诉你……还是再深入分析一下吧!用下面的代码去分析:
int main()
{
int pid;
int ppid;
if( signal( SIGRTMIN, sigusr1 ) == SIG_ERR ){
perror( "Can not catch SIGRTMIN!" );
}
if( (pid=fork()) == -1 )
perror("fork error!");
else if( pid == 0 ) /*child deal*/
{
sleep(1);
printf ( "the pid is %d\n", getpid() );
ppid = getppid();
printf ( "the ppid is %d\n", ppid );
kill( ppid, SIGRTMIN );
}
if( (pid=fork()) == -1 )
perror("fork");
else if( pid == 0 ) /*child deal*/
{
printf ( "the pid is %d\n", getpid() );
ppid = getppid();
printf ( "the ppid is %d\n", ppid );
kill( ppid, SIGRTMIN );
sleep(2);
}
sleep(3);
return 0;
}
看一下吧,添加了这些语句,你应该有了新的想法,对了,就是这样,fork函数创建的子进程要继承(写时复制)父进程的用户空间,也就是相应的代码段和数据段,不过它的下一步执行是从被创建的那一点开始的,也就是说第一个子进程在被创建后也执行了下面的代码,打印了aa,创建了子进程,打印了bb,这样第二个fork函数就被执行了两次,创建了两个新的子进程,这两个子进程的区别就是父进程不同,他们都执行了后面的sleep并且打印了bb,所以总共有三个子进程,也就发送了三个信号,bb也就被打印了四次!
阅读(1164) | 评论(1) | 转发(0) |