Linux中进程间使用无名管道通信。
使用pipe()函数创建无名管道。
利用管道进行通信时,管道中无数据时,读操作会阻塞,管道满时,写操作会阻塞。即保证了一次只有一个进程访问管道,满足了互斥的需求。
在程序中,四个子进程共用一个管道,实现十万个数相加,每个进程实现两万个数相加,并把结果传递给父进程,父进程再把四个子进程的结果相加。
代码:
/*date:2021-05-07
* author:liyang*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
int main(){
int fd[2];
int ok = pipe(fd);//创建管道,让四个子进程共享
double parent_sum = 0.0;
double n[100000];
for(int i = 0;i < 100000;i++){
srand((unsigned)(time(NULL)+i));
n[i] = ((double)rand())/RAND_MAX;
parent_sum += n[i];//父进程先求和
}
int pid_1 = fork();//第一个子进程
if(pid_1==0){
for(int i = 1;i < 25000;i++) n[0]+=n[i];
printf("(%d) Chlid_1 sum:%f\n",getpid(),n[0]);
close(fd[0]);
write(fd[1],&n[0],sizeof(double));
//把结果写入管道
}
if(pid_1 > 0){
int pid_2 = fork();//第二个子进程
if(pid_2==0){
for(int i = 25001;i < 50000;i++) n[25000]+=n[i];
printf("(%d) Chlid_2 sum:%f\n",getpid(),n[25000]);
close(fd[0]);
write(fd[1],&n[25000],sizeof(double));
//把结果写入管道
}
if(pid_2 > 0){
int pid_3= fork();//第三个子进程
if(pid_3==0){
for(int i = 50001;i < 75000;i++) n[50000]+=n[i];
printf("(%d) Chlid_3 sum:%f\n",getpid(),n[50000]);
close(fd[0]);
write(fd[1],&n[50000],sizeof(double));
//把结果写入管道
}
if(pid_3 > 0){
int pid_4 = fork();//第四个子进程
if(pid_4==0){
for(int i = 75001;i < 100000;i++) n[75000]+=n[i];
printf("(%d) Chlid_4 sum:%f\n",getpid(),n[75000]);
close(fd[0]);
write(fd[1],&n[75000],sizeof(double));
//把结果写入管道
}
if(pid_4 > 0){
double children_sum = 0.0;
double children_read;
for(int i = 0;i < 4;i++){
close(fd[1]);
read(fd[0],&children_read,sizeof(double));
//从管道中读一个数
children_sum += children_read;
}
printf("(%d) Parent direct sum:%f,sum from Children:%f\n",getpid(),parent_sum,children_sum);
}
}
}
}
}
运行: