免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 8612 | 回复: 6
打印 上一主题 下一主题

[C] LINUX 使用fork函数进行多进程编程的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-31 22:19 |只看该作者 |倒序浏览
要求:有3个进程,其中一个为父进程,其余两个是该父进程创建的子进程,其中一个子进程运行“ls -l”指令,另一个子进程在暂停5s后异常退出。父进程先用阻塞方式等待第一个进程的结束,然后用非阻塞方式等待另一个子进程的退出,待收集到第2个子进程结束的消息后,父进程就返回。代码如下:
  1. /* multi_proc_wrong.c文件 */
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. #include<sys/types.h>
  5. #include<unistd.h>
  6. #include<sys/wait.h>

  7. int main()
  8. {
  9.         pid_t child1,child2,child;
  10.         /*创建两个子进程*/
  11.         child1=fork();
  12.         child2=fork();
  13.         /*子进程1的出错处理*/
  14.         if(child1==-1)
  15.         {
  16.                 printf("Child1 fork error\n");
  17.                 exit(1);  /*异常退出*/
  18.         }
  19.         /*在子进程1中调用execlp()函数*/
  20.         else if(child1==0)
  21.         {
  22.                 printf("I am child1 and I execute 'ls -l'\n");
  23.                 if(execlp("ls","ls","-l",NULL)<0)
  24.                 {
  25.                         printf("Child1 execlp error\n");
  26.                 }
  27.         }
  28.         /*子进程2的出错处理*/
  29.         if(child2==-1)
  30.         {
  31.                 printf("Child2 fork error\n");
  32.                 exit(1);  /*异常退出*/
  33.         }
  34.         /*在子进程2中使其暂停5s*/
  35.         else if(child2==0)
  36.         {
  37.                         printf("I am child2.I will sleep for 5 seconds!\n");
  38.                         sleep(5);
  39.                         printf("I am child2.I have awaked and I will exit!\n");
  40.                         exit(0); /*正常退出*/
  41.         }
  42.         /*在父进程中等待两个子进程的退出*/
  43.         else
  44.         {
  45.                 printf("I am father progress\n");
  46.                 child=waitpid(child1,NULL,0);/*阻塞式等待*/
  47.                 if(child==child1)
  48.                 {
  49.                         printf("I am father progress.I get child1 exit code:%d\n",child);
  50.                 }
  51.                 else
  52.                 {
  53.                         printf("Error occured!\n");
  54.                 }

  55.                 do
  56.                 {
  57.                         child=waitpid(child2,NULL,WNOHANG);/*非阻塞式等待*/
  58.                         if(child==0)
  59.                         {
  60.                                 printf("I am father progress.The child2 progress has not exited!\n");
  61.                                 sleep(1);
  62.                         }
  63.                 }while(child==0);

  64.                 if(child==child2)
  65.                 {
  66.                         printf("I am father progress.I get child2 exit code:%d\n",child);
  67.                 }
  68.                 else
  69.                 {
  70.                         printf("Erroe occured!\n");
  71.                 }
  72.         }
  73.         exit(0);
  74. }
复制代码
程序是错误的。运行结果显示产生了两个完成"ls -l"的进程child1。我的疑问是为什么不是产生了两个child2功能的进程呢?

论坛徽章:
0
2 [报告]
发表于 2013-12-31 22:46 |只看该作者
本帖最后由 aimerjing 于 2013-12-31 22:47 编辑

以上代码运行结果如下:

论坛徽章:
0
3 [报告]
发表于 2013-12-31 22:48 |只看该作者
错误代码运行结果如下图

130612110861595.png (98.2 KB, 下载次数: 88)

130612110861595.png

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
4 [报告]
发表于 2013-12-31 23:40 |只看该作者
本帖最后由 MMMIX 于 2013-12-31 23:42 编辑

回复 1# aimerjing


    代码行为解释:
1、第二个 fork() 被执行了两遍,所以最终会有 4 个进程;
2、在第二个 fork() 执行之前,第一个 fork() 的子进程中 child1 已经是 0 了,再结合你条件判断的顺序,这个 child1 为零的子进程执行第二个 fork() 之后生成的父子两个进程都会执行 ls。
3、在第一个 fork() 生成的父进程中,child1 不为零,其执行第二个 fork() 之后生成的父子进程中,父进程会执行 wait(),而子进程会执行 sleep 五秒然后退出的动作。

画个进程结构图,在其中把 child1 和 child2 的值标出来可以帮助你理解它们之间的关系和该代码的行为。

论坛徽章:
0
5 [报告]
发表于 2013-12-31 23:53 |只看该作者
谢谢,我试试回复 4# MMMIX


   

论坛徽章:
0
6 [报告]
发表于 2014-01-02 10:04 |只看该作者
fork两次,如果第一次成功,第二次的时候父子进程都fork了自己的子进程,也就是说,你再是3个进程而是4个了,还是看看程序的处理逻辑吧。

论坛徽章:
0
7 [报告]
发表于 2014-01-02 19:50 |只看该作者
多谢,现在弄明白了回复 6# dididimeme01


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP