博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[操作系统作业]os实验三:进程的管道通信
阅读量:6354 次
发布时间:2019-06-22

本文共 4810 字,大约阅读时间需要 16 分钟。

View Code
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define PSIZE 211 12 int main(){13 int fd[2];14 int flag = 1;15 //16 if((flag = pipe(fd)) == -1){17 printf("error in create pipe.");18 exit(1);19 }else if(flag == 0){20 // printf("success in create pipe.");21 }22 23 pid_t pid_1,pid_2;24 char outpipe[50];25 // ******************问题所在********************//26 if(((pid_1 = fork()) == -1)||((pid_2 = fork()) == -1)){27 // ******************问题所在********************//28 printf("error in fork()!");29 }30 else if(pid_1 == 0){31 printf("\n ...................%d %d...................\n",pid_1,pid_2);32 printf("i am a child 1, my pid is %d ,my fatherpid is %d.\n",getpid(),getppid());33 lockf(fd[1],1,0);// 对管道的写入端口jia锁。34 strcpy(outpipe,"Child process 1 is sending message!\n");35 printf("i am a child, i am writing %s \n",outpipe);36 write(fd[1],outpipe,sizeof(outpipe));37 sleep(5);38 lockf(fd[1],0,0);// 对管道的写入端口解锁。39 //getchar();//must write40 exit(0);41 }else if(pid_2 == 0){42 printf("\n ...................%d %d...................\n",pid_1,pid_2);43 44 printf("i am a child 2, my pid is %d ,my fatherpid is %d..\n",getpid(),getppid());45 lockf(fd[1],1,0);// 对管道的写入端口jia锁。46 strcpy(outpipe,"Child process 2 is sending message!");47 printf("i am a child, i am writing %s \n",outpipe);48 write(fd[1],outpipe,sizeof(outpipe));49 sleep(5);50 lockf(fd[1],0,0);// 对管道的写入端口解锁。51 //getchar();//must write52 exit(0);53 }else if(pid_1 > 0&&pid_2>0){54 printf("i am father, my pid is %d, my sonpid is %d and %d.\n",getpid(),pid_1,pid_2);55 int i = 0;56 pid_t pid;57 while(i < PSIZE){58 if((pid = wait(0)) < 0){59 printf("error in waitepid.\n");60 exit(1);61 }else{62 read(fd[0],outpipe,sizeof(outpipe));63 printf("father process read from pipe : %s son pid is %d.\n",outpipe,pid);64 }65 i++;66 }67 //getchar();//must write, if not ,the son process will be an orphen process. 相当于停了一下68 exit(0);69 }70 }
错误在于父进程同时fork()生成两个子进程。
子进程有可能在连续fork过程中生成自己的子进程,是否生成与子进程执行的顺序相关。
简要说明:
执行顺序(应该是运行结果更恰当)
父进程:(pid :2000)
fork()(子进程pid :2001)||fork()(子进程pid :2002)
子进程2:(pid :2002)
fork()(子进程pid :
2001)||fork()(子进程pid :
0
子进程1:(pid :2001)
fork()(子进程pid :   
0   )||fork()(子进程pid :
2003
子进程至少保证了与所属父进程在调用fork()的位置处,fork()返回值为 0.
但是子进程继续fork(),返回值就与各进程的执行顺序相关了。
具体,比如 子进程2:pid
2001,我认为是由于父进程刚第一次fork,子进程2就fork了,那返回值为什么不是0呢?
这个问题我也不知到,欢迎大家指正。应该跟编译器有关。
最后结论:
父进程可以fork多个子进程,但是得一个一个fork,必须使得每fork一次后都需要有控制语句将其父子进程执行的程序段完全隔离开。避免使用 fork()||fork()连续fork子进程。
 
修改后:
View Code
1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #define PSIZE 211 12 int main(){13 int fd[2];14 int flag = 1;15 if((flag = pipe(fd)) == -1){ //创建管道16 printf("error in create pipe.");17 exit(1);18 }else if(flag == 0){19 // printf("success in create pipe.");20 }21 pid_t pid_1,pid_2;22 char outpipe[50];23 if((pid_1 = fork()) == -1){ //创建子进程24 printf("error in fork()!");25 }else if(pid_1 == 0){ //子进程执行代码段26 printf("i am child 1, my pid is %d ,my fatherpid is %d.\n",getpid(),getppid());27 lockf(fd[1],1,0);// 对管道的写入端口jia锁。28 strcpy(outpipe,"Child process 1 is sending message!\n");29 printf("i am writing : %s \n",outpipe);30 write(fd[1],outpipe,sizeof(outpipe));31 sleep(5);// 让自己睡眠,好让父进程读出pipe内的数据。32 lockf(fd[1],0,0);// 对管道的写入端口解锁。33 //getchar();//must write34 exit(0);35 }else if(pid_1 > 0){ //父进程执行代码段36 if((pid_2 = fork()) == -1){37 printf("error in fork()!");38 }else if(pid_2 == 0){39 printf("i am child 2, my pid is %d ,my fatherpid is %d..\n",getpid(),getppid());40 lockf(fd[1],1,0);// 对管道的写入端口jia锁。41 strcpy(outpipe,"Child process 2 is sending message!");42 printf("i am writing : %s \n",outpipe);43 write(fd[1],outpipe,sizeof(outpipe));44 sleep(5);45 lockf(fd[1],0,0);// 对管道的写入端口解锁。46 //getchar();//must write47 exit(0);48 }49 printf("i am father, my pid is %d, my son pid is %d and %d.\n",getpid(),pid_1,pid_2);50 int i = 0;51 pid_t pid;52 while(i < PSIZE){53 if((pid = wait(0)) < 0){ //等待子进程结束后返回,返回值为子进程pid54 printf("error in waitepid.\n");55 exit(1);56 }else{57 read(fd[0],outpipe,sizeof(outpipe));58 printf("father process read from pipe : %s from son pid: %d.\n",outpipe,pid);59 }60 i++;61 }62 //getchar();//must write, if not ,the son process will be an orphen process. 相当于停了一下63 exit(0);64 }65 }

关键在于子进程2,是如何执行父子共享代码段的。

 

修正:

wait函数,父进程需等待子进程结束后返回,才可继续执行

因此,code中 子进程1,2的程序段中的sleep函数的作用:保证子进程将数据全部写入管道。

而非等待以保证父进程从管道中读出数据。

 

 

 

转载于:https://www.cnblogs.com/wanping/archive/2012/06/01/2531407.html

你可能感兴趣的文章
[LeetCode] Spiral Matrix 解题报告
查看>>
60906磁悬浮动力系统应用研究与模型搭建
查看>>
指纹获取 Fingerprint2
查看>>
面试题目3:智能指针
查看>>
取消凭证分解 (取消公司下的多个利润中心)
查看>>
flask ORM: Flask-SQLAlchemy【单表】增删改查
查看>>
vim 常用指令
查看>>
nodejs 获取自己的ip
查看>>
Nest.js 处理错误
查看>>
你好,C++(16)用表达式表达我们的设计意图——4.1 用操作符对数据进行运算...
查看>>
18.3 redis 的安装
查看>>
jdbc 简单连接
查看>>
Activiti 实战篇 小试牛刀
查看>>
java中的Static class
查看>>
[工具类]视频音频格式转换
查看>>
GNS3与抓包工具Wireshark的关联
查看>>
groovy-语句
查看>>
VIM寄存器使用
查看>>
Java VisualVM远程监控JVM
查看>>
nasm预处理器(2)
查看>>