有关Linux下父子进程之间的几个思考与结论
来源:互联网 发布:ubuntu怎么连接宽带 编辑:程序博客网 时间:2024/05/16 07:53
From: http://wzw19191.blog.163.com/blog/static/1311354702009926105428947/
1
. 父进程可以利用wait()/ waitpid()等待子进程的结束,避免僵死子进程的产生,当然也可以循环的wait()/ watipid()来等待所有的子进程的结束;最好可以用法是,在子进程结束时,会向父进程发送的SIGCHLD信号,父进程通过 signal()/sigaction()来响应子进程的结束.具体实例可参考:TestFork4.c,关键代码如下:
signal(SIGCHLD, sigchld_handler);
void sigchld_handler(int sig)
{
pid_t pid;
int status;
for(; (pid =waitpid(-1, &status, WNOHANG)) >0;)
{
printf("child %d died:%d/n", pid, WEXITSTATUS(status));// pid, status);
}
//while((pid =waitpid(-1, &status, WNOHANG))>0){}
return;
}
2 . 当父进程结束时,还未结束的子进程就会成为孤儿进程,系统会把init进程作为其父进程;从而使得子进程在父进程结束后,继续运行.
3 . 对于父子进程共存时,产生相关信号如SIGINT时,父子进程都能接受到此信号,只是先由父进程响应,再由父进程把此信号传递给子进程;但要注意的地方是:(1)如父进程没有对该信号进程自定义处理,则父子进程都接受信号的默认处理,eg:在没有对SIGINT进程自定义处理时,产生此信号,由父子进程都马上中止;(2)如父进程自定义了信号处理方法,则子进程一样接受此信号和其信号处理方法;此时,若子进程成为孤儿进程,则此时的子进程不会再接受此信号和其信号处理方法.具体实例可参考 TestFork6.c,关键代码如下:
signal(SIGINT, sig_handler);
for(i =0; i<5; i++)
{
if(fork() ==0)
{
printf("child %d/n", getpid());
sleep(5);//此刻,响应SIGINT信号,且信号处理完后唤醒进程
printf("after sleep1:child %d/n", getpid());
sleep(5);//到此刻,子进程成为孤儿进程,因此不再响应SIGINT信号
printf("after sleep2:child %d/n", getpid());
exit(0);
}
}
4 . 在创建子进程时,内核将父进程的很多内容拷贝给子进程,同时在调用fork()后,父子进程共享正文部分(其实也相当于拷贝);注意拷贝两字,所以子进程中修改的东东对父进程没有作用,除非利用父子进程通信方法;因此,要特别注意子进程的代码编写,如动态空间的释放问题,内存信号修改问题;具体实例可参考:TestFork1.c,关键代码如下:
gets(buf);
pid =fork();
if(pid ==0)
{
printf("child:");
strcpy(buf, "xiaofeng");
//此处的buf(为主进程中buf的一个副本)与else(主进程)中的buf无关,因为对其修改不会影响主进程中buf的内容
}
else
{
printf("parent:");
sleep(5);
}
printf("%s/n", buf);//此处输出结果处决于该语句位于哪个进程(父/子进程)
结果:(hello 为gets(buf)语句)
hello
child:xiaofeng
parent:hello
signal(SIGCHLD, sigchld_handler);
void sigchld_handler(int sig)
{
pid_t pid;
int status;
for(; (pid =waitpid(-1, &status, WNOHANG)) >0;)
{
printf("child %d died:%d/n", pid, WEXITSTATUS(status));// pid, status);
}
//while((pid =waitpid(-1, &status, WNOHANG))>0){}
return;
}
2 . 当父进程结束时,还未结束的子进程就会成为孤儿进程,系统会把init进程作为其父进程;从而使得子进程在父进程结束后,继续运行.
3 . 对于父子进程共存时,产生相关信号如SIGINT时,父子进程都能接受到此信号,只是先由父进程响应,再由父进程把此信号传递给子进程;但要注意的地方是:(1)如父进程没有对该信号进程自定义处理,则父子进程都接受信号的默认处理,eg:在没有对SIGINT进程自定义处理时,产生此信号,由父子进程都马上中止;(2)如父进程自定义了信号处理方法,则子进程一样接受此信号和其信号处理方法;此时,若子进程成为孤儿进程,则此时的子进程不会再接受此信号和其信号处理方法.具体实例可参考 TestFork6.c,关键代码如下:
signal(SIGINT, sig_handler);
for(i =0; i<5; i++)
{
if(fork() ==0)
{
printf("child %d/n", getpid());
sleep(5);//此刻,响应SIGINT信号,且信号处理完后唤醒进程
printf("after sleep1:child %d/n", getpid());
sleep(5);//到此刻,子进程成为孤儿进程,因此不再响应SIGINT信号
printf("after sleep2:child %d/n", getpid());
exit(0);
}
}
4 . 在创建子进程时,内核将父进程的很多内容拷贝给子进程,同时在调用fork()后,父子进程共享正文部分(其实也相当于拷贝);注意拷贝两字,所以子进程中修改的东东对父进程没有作用,除非利用父子进程通信方法;因此,要特别注意子进程的代码编写,如动态空间的释放问题,内存信号修改问题;具体实例可参考:TestFork1.c,关键代码如下:
gets(buf);
pid =fork();
if(pid ==0)
{
printf("child:");
strcpy(buf, "xiaofeng");
//此处的buf(为主进程中buf的一个副本)与else(主进程)中的buf无关,因为对其修改不会影响主进程中buf的内容
}
else
{
printf("parent:");
sleep(5);
}
printf("%s/n", buf);//此处输出结果处决于该语句位于哪个进程(父/子进程)
结果:(hello 为gets(buf)语句)
hello
child:xiaofeng
parent:hello
5 . 补充下有关信号的几个结论:
(1)信号处理有三种模式,一为默认处理方式;二为信号忽略方式;三为自定义信号处理方法;
(2) 当一个进程睡眠在可中断优先级时,进程捕获的信号将中断进程的睡眠
- 有关Linux下父子进程之间的几个思考与结论
- 有关Linux下父子进程内容
- 父子进程之间的区别
- 父子进程之间的关系
- Linux下父子进程拾遗
- 有关linux下多进程与多线程的区别总结
- linux下有关时间的几个函数
- 有关Linux下的几个解压缩命令
- linux下的父子进程的验证代码
- Linux下的管道和父子进程的应用
- linux下父子进程间的通信——管道
- 寻根1:unix/linux下的父子进程交互
- fork 父子进程变量之间的关系
- 父子进程之间数据的同步
- Linux shell脚本中父子进程与变量的分析
- Linux shell脚本中父子进程与变量的分析
- Linux shell脚本中父子进程与变量的分析
- windows下有关端口和进程PID之间的关联
- struts中登录后用户信息保存注意
- windows下使用MinGW编译QPSQL插件
- 工作两年了
- style详解
- Mysql 获取自增Id
- 有关Linux下父子进程之间的几个思考与结论
- 浅聊SSH替代Telnet cisco路由器配置宝典
- AxWindowsMediaPlayer媒体文件主要方法属性
- 我们用到的软件
- 关于感染型病毒的那些事(一)
- 清远古龙峡漂流、新银盏温泉两天游活动方案
- USACO 1.3-Calf Flac
- 类Unix系统概述
- VC-1