说明如何实现父子进程之间的同步的,#include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <error.h> #include <wait.h> #include <unistd.h> int main( ){ int pid1,pid2,pid3; int fd[2]; char outpipe[60],inpipe[60]; pipe(fd);//创建一个管道 while ((pid1=fork( ))==-1); printf("pid1=%d\n",pid1); if(pid1==0){ printf("The Child process 1 is sending message!\n"); lockf(fd[1],1,0);//互斥 sprintf(outpipe,"This is the child 1 process's message!\n"); write(fd[1],outpipe,60); sleep(1);//自我阻塞1秒,让出机会执行下一个进程,增加并发度 lockf(fd[1],0,0); exit(0); } else{ while((pid2=fork( ))==-1); printf("pid2=%d\n",pid2); if(pid2==0){ printf("The Child process 2 is sending message!\n"); lockf(fd[1],1,0); sprintf(outpipe,"This is the child 2 process's message!\n"); write(fd[1],outpipe,60); sleep(1); lockf(fd[1],0,0); exit(0); } else{ while((pid3=fork( ))==-1); printf("pid3=%d\n",pid3); if(pid3==0){ printf("The Child process 3 is sending message!\n"); lockf(fd[1],1,0); sprintf(outpipe,"This is the child 3 process's message!\n"); write(fd[1],outpipe,60); sleep(1); lockf(fd[1],0,0); exit(0); } else{ wait(0);//同步 read(fd[0],inpipe,60); printf("\n%s",inpipe); wait(0); read(fd[0],inpipe,60); printf("%s\n",inpipe); wait(0); read(fd[0],inpipe,60); printf("%s\n",inpipe); exit(0); } } } return 0; }
时间: 2024-03-30 13:37:29 浏览: 16
在这个程序中,父进程通过创建三个子进程并使用管道进行通信,实现了父子进程之间的同步操作。具体实现方法如下:
首先,父进程在创建三个子进程之前创建了一个管道,并将其用于子进程之间的通信。
接着,父进程创建了三个子进程,每个子进程都会执行以下操作:
1. 使用 lockf 函数进行互斥锁,确保每个子进程都能独占写入管道的操作,避免产生竞争条件。
2. 将子进程要发送的信息写入管道中。
3. 自我阻塞一秒钟,让出 CPU 资源,从而增加并发度。
4. 使用 lockf 函数释放互斥锁。
5. 子进程退出。
最后,父进程使用 wait 函数等待三个子进程都执行完毕,然后依次从管道中读取子进程发送的信息,并输出到屏幕上。
通过这种方式,父子进程之间就能够实现同步操作,确保各个子进程的执行顺序和输出顺序都能够正确无误。
相关问题
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main() { pid_t pid; pid = fork(); if (pid < 0) { perror("fork fail\n"); exit(-1); } else if ( pid == 0 ) // 子进程1 { printf("b\n"); sleep(5); exit(0); } else { printf("a\n"); // 父进程 waitpid(pid,NULL,0); printf("my son has exit!\n"); exit(0); } }的waitpid(pid,NULL,0)有什么用
waitpid(pid,NULL,0)是父进程等待子进程结束的一种方式。其中,pid是子进程的进程ID,NULL表示不需要获取子进程的结束状态,0表示等待任何子进程结束。
在该代码中,父进程通过waitpid函数等待子进程结束,以确保子进程在父进程之前结束。如果不等待子进程结束,父进程可能会在子进程之前退出,导致子进程变成孤儿进程,从而由init进程接管,造成资源浪费和系统性能降低。
因此,使用waitpid函数可以保证父子进程的正确协同执行。
#include <stdio.h> #include <sys/types.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> #include <error.h> #include <wait.h> #include <unistd.h> int main( ){ int pid1,pid2,pid3; int fd[2]; char outpipe[60],inpipe[60]; pipe(fd);//创建一个管道 while ((pid1=fork( ))==-1); printf("pid1=%d\n",pid1); if(pid1==0){ printf("The Child process 1 is sending message!\n"); lockf(fd[1],1,0);//互斥 sprintf(outpipe,"This is the child 1 process's message!\n"); write(fd[1],outpipe,60); sleep(1);//自我阻塞1秒,让出机会执行下一个进程,增加并发度 lockf(fd[1],0,0); exit(0); } else{ while((pid2=fork( ))==-1); printf("pid2=%d\n",pid2); if(pid2==0){ printf("The Child process 2 is sending message!\n"); lockf(fd[1],1,0); sprintf(outpipe,"This is the child 2 process's message!\n"); write(fd[1],outpipe,60); sleep(1); lockf(fd[1],0,0); exit(0); } else{ while((pid3=fork( ))==-1); printf("pid3=%d\n",pid3); if(pid3==0){ printf("The Child process 3 is sending message!\n"); lockf(fd[1],1,0); sprintf(outpipe,"This is the child 3 process's message!\n"); write(fd[1],outpipe,60); sleep(1); lockf(fd[1],0,0); exit(0); } else{ wait(0);//同步 read(fd[0],inpipe,60); printf("\n%s",inpipe); wait(0); read(fd[0],inpipe,60); printf("%s\n",inpipe); wait(0); read(fd[0],inpipe,60); printf("%s\n",inpipe); exit(0); } } } return 0; }(1)(1)指出父进程与三个子进程并发执行的顺序,并说明原因。(2)说明是如何实现父子进程之间的同步的(3)源代码中,如果父进程执行读消息四次什么结果?(4)修改代码,父进程发送消息,三个子进程分别读。
(1) 父进程与三个子进程的并发执行顺序是不确定的,取决于操作系统的调度算法和进程的执行速度。在这段代码中,通过自我阻塞 1 秒和使用 `lockf()` 函数对管道进行互斥的方式,增加了子进程之间的并发度,从而使它们更有可能在父进程执行之前完成。但是,具体的执行顺序是不可预测的。
(2) 父进程与子进程之间的同步是通过 `wait()` 函数实现的。在父进程中调用 `wait()` 函数可以等待子进程退出,并获取子进程的退出状态。在这段代码中,父进程调用了三次 `wait()` 函数,分别等待三个子进程退出。
(3) 如果父进程执行读消息四次,那么它会从管道中读取三条消息和一条空消息。因为管道是一个先进先出的队列,如果管道中没有消息,那么 `read()` 函数会立即返回,并且不会阻塞进程。
(4) 修改代码,父进程发送消息,三个子进程分别读的示例代码如下:
```c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <error.h>
#include <wait.h>
#include <unistd.h>
int main( ){
int pid1, pid2, pid3;
int fd[2];
char outpipe[60], inpipe[60];
pipe(fd);//创建一个管道
while ((pid1=fork( ))==-1);
printf("pid1=%d\n",pid1);
if(pid1==0){
exit(0);
} else{
while((pid2=fork( ))==-1);
printf("pid2=%d\n",pid2);
if(pid2==0){
exit(0);
} else{
while((pid3=fork( ))==-1);
printf("pid3=%d\n",pid3);
if(pid3==0){
exit(0);
} else{
// 父进程发送消息
printf("The parent process is sending message!\n");
sprintf(outpipe, "This is the parent process's message!\n");
write(fd[1], outpipe, 60);
sleep(1);
// 子进程分别读取消息
read(fd[0], inpipe, 60);
printf("Child process 1: %s", inpipe);
read(fd[0], inpipe, 60);
printf("Child process 2: %s", inpipe);
read(fd[0], inpipe, 60);
printf("Child process 3: %s", inpipe);
exit(0);
}
}
}
return 0;
}
```
在这个示例中,父进程先向管道中写入一条消息,然后三个子进程分别从管道中读取这条消息,并打印出来。
相关推荐
![text/x-c](https://img-home.csdnimg.cn/images/20210720083646.png)
![text/x-c](https://img-home.csdnimg.cn/images/20210720083646.png)
![image/gif](https://img-home.csdnimg.cn/images/20210720083352.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![-](https://csdnimg.cn/download_wenku/file_type_column_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)