关于linux下fork函数和signal函数的使用
今天一直在研究嵌入式的实验作业,有一组代码一直没想明白,百度搜到了许多和我相同实验的同学,但是没有一个解除了我的疑惑。在对代码中每个函数进行了仔细的研究后,终于把代码来龙去脉弄懂了。SIGINT指令=Ctrl+c最主要坑的还是fork()创建的子进程会完完全全克隆他的父进程,包括父进程当前的代码段,也就是fork()之后,父进程执行到哪一步了,子进程就从哪一步开始执行。子进程也会复制 父进程之
今天一直在研究嵌入式的实验作业,有一组代码一直没想明白,百度搜到了许多和我相同实验的同学,但是没有一个解除了我的疑惑。在对代码中每个函数进行了仔细的研究后,终于把代码来龙去脉弄懂了。
SIGINT指令=Ctrl+c
最主要坑的还是fork()创建的子进程会完完全全克隆他的父进程,包括父进程当前的代码段,也就是fork()之后,父进程执行到哪一步了,子进程就从哪一步开始执行。
子进程也会复制 父进程之前的 监听函数,例如下面代码中的
signal(SIGINT,stop);
子进程也会复制这个函数,所以当你按下ctrl+c时,父进程和子进程都会调用stop函数。
以下是代码以及注释:
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
int wait_mark;
void waiting(), stop();
int main(int argc, char *argv[]) {
int p1, p2;
signal(SIGINT,stop); //监听ctrl+c,如果按下了,则执行stop函数
while((p1 = fork()) == -1);//这里创建了一个子进程,子进程和父进程一样也开始监听ctrl+c
if (p1 > 0) /*在父进程中*/
{ ①
while((p2 = fork()) == -1); //再创建一个子进程,同样也监听ctrl+c
if ( p2 > 0) /*在父进程中*/
{ ②
wait_mark = 1;
waiting();//只要wait_mark等于1,就会一直等待。而执行stop函数后,wait_mark=0了就跳出了循环。
kill(p1, 10);//在这段代码中这个方法相当于没啥用,这个函数给p1发送了10的指令,让p1进程再执行一次stop方法。
kill(p2, 12);//原理同上
wait(NULL);//等待子程序结束
wait(NULL);//同上
printf("parent process exit!\n");
exit(0);
}
else /*在子进程 2 中*/
{
wait_mark = 1;
signal(12, stop);
waiting();//只要wait_mark等于1,就会一直等待。而执行stop函数后,wait_mark=0了就跳出了循环。
lockf(1, 1, 0);
printf("child process 2 is killed by parent!\n");
lockf(1, 0, 0);
exit(0);
}
}
else /*在子进程 1 中*/
{
wait_mark = 1;
signal(10, stop);
waiting();//只要wait_mark等于1,就会一直等待。而执行stop函数后,wait_mark=0了就跳出了循环。
lockf(1, 1, 0);
printf("child process 1 is killed by parent!\n");
lockf(1, 0, 0);
exit(0);
}
}
void waiting()
{
while(wait_mark != 0);
}
void stop()
{
wait_mark = 0;
}
最开始父进程,p1进程,p2都在wait()中等待,当按下ctrl+c时,父进程,p1进程,p2进程三个进程都监听到了ctrl+c,都会执行stop函数,从而把3个进程内的wait_mark置为0,跳出循环。所以才会顺序执行输出这3句话。
所以
kill(p1, 10);//在这段代码中这个方法相当于没啥用,这个函数给p1发送了10的指令,让p1进程再执行一次stop方法。
kill(p2, 12);//同上
这两个函数没起到作用,可以直接注释掉,无伤大雅。
之后老师又给出了一个问题
⑴ 如果把signal(SIGINT,stop)放在①号和②号位置,结果会怎样并分析原因。
signal(SIGINT,stop)放在①号位置时,子进程p1就监听不到signal(SIGINT,stop)了,而ctrl+c本身就有一个中断进程的作用,这时候如果按下了ctrl+c,p1直接被中断,不再等待了,也不执行子进程之后的代码了。
执行结果:
signal(SIGINT,stop)放在②号位置时,子进程p1、p2就监听不到signal(SIGINT,stop)了,而ctrl+c本身就有一个中断进程的作用,这时候如果按下了ctrl+c,p1、p2直接被中断,不再等待了,也不执行之后的代码了。
执行结果:
所以
kill(p1, 10);//在这段代码中这个方法相当于没啥用,这个函数给p1发送了10的指令,让p1进程再执行一次stop方法。
kill(p2, 12);//同上
这两个函数实际上又没起到作用。
就是这个坑,排了挺久的,主要还是自己对函数的原理不太熟悉。
更多推荐
所有评论(0)