操作系统:进程通信

一、进程管道
1.读管道
(1)代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
FILE *read_fp; 
char buffer[BUFSIZ+1]; 
int chars_read;
memset(buffer,‘\0,sizeof(buffer)); 
read_fp=popen(“uname -a”,“r”); 
if(read_fp!=NULL){
chars_read=fread(buffer,sizeof(char),BUFSIZ,read_fp); 
if(chars_read>0) printf(“Output was:-\n%s\n”,buffer);
pclose(read_fp); 
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
2.写管道
(1)代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
FILE *write_fp;   //文件流指针
char buffer[BUFSIZ+1];    //缓冲区
sprintf(buffer,"Once upon a time, there was...\n");
write_fp=popen("wc -w","w");
if(write_fp!=NULL){
fwrite(buffer,sizeof(char),strlen(buffer),write_fp);
pclose(write_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
二、匿名管道
通过 pipe 函数创建匿名管道,在两个进程间传递数据,而不需要启动一个 shell 来解释请求的命令。该管道工作在更底层,访问管道,使用文件描述符而不是文件流,所以使用系统调用 read 和 write 来访问管道数据。
1.生产者/消费者的管道模型
(1)代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
int data_processed;
int file_pipes[2]; 
const char some_data[]="123";
char buffer[BUFSIZ+1]; //缓冲区
memset(buffer,'\0',sizeof(buffer)); //初始化缓冲区
if(pipe(file_pipes)==0){ 
data_processed= write(file_pipes[1],some_data,strlen(some_data)); 
printf("Wrote %d bytes\n",data_processed);
data_processed=read(file_pipes[0],buffer,BUFSIZ); 
printf("Read %d bytes: %s\n",data_processed,buffer);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
2.父子进程通过管道通信
(1)代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
int data_processed;
int file_pipes[2]; 
const char some_data[]="123";
char buffer[BUFSIZ+1];
pid_t pid;
 memset(buffer,'\0',sizeof(buffer));
if(pipe(file_pipes)==0){ //同上
pid=fork(); //创建子进程
if(pid == -1){
fprintf(stderr,"Fork failure");
exit(EXIT_FAILURE);
}
if(pid==0){ //子进程并发执行
data_processed=read(file_pipes[0],buffer, BUFSIZ); //读管道
printf("Read %d bytes: %s\n", data_processed,buffer);
exit(EXIT_SUCCESS);
}
else{ //父进程并发执行
data_processed=write(file_pipes[1], some_data, strlen(some_data));
printf("Wrote %d bytes\n",data_processed);
}
}
exit(EXIT_SUCCESS);
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.利用信号量实现父子同步通信
(1)代码:

#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
void err_printf(char *p)
{
    printf("%s\n",p);
    exit(0);
}
int main(void)
{
        int fd1[2],fd2[2];
        pid_t pid;
        char *str="the data from parent process.\n";
        char *dtr="the data from child process.\n";
        char buf[1024];
        if(pipe(fd1)<0)
                err_printf("pipe fd1 fail");
        if(pipe(fd2)<0)
                err_printf("pipe fd2 fail");
        if((pid=fork())<0)
                err_printf("fork fail");
        else if(pid==0)
        {       
                close(fd1[1]);
                close(fd2[0]);
                //子进程读取数据
                int num=read(fd1[0],buf,sizeof(buf));
                //在终端打印
                write(STDOUT_FILENO,buf,num);
                puts("child recevied the parent message\n");
                //子进程向父进程写东西
                write(fd2[1],dtr,strlen(dtr)+1);
          }
          else
          {
                close(fd1[0]);
                close(fd2[1]);
                write(fd1[1],str,strlen(str)+1);
                int num=read(fd2[0],buf,sizeof(buf));
                puts("parent recevied the child message\n");
                write(STDOUT_FILENO,buf,num);
           }
            exit(0);
            return 0;
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
三、命名管道 FIFO(常用在不相关进程间交换数据)
1.shell 命令创建命名管道:$ mkfifo /tmp/my_fifo
查看命名管道命令:$ ls –lF /tmp/my_fifo
2. 程序创建命名管道
(1)代码:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc,char *argv[]){
int res = mkfifo("/tmp/my_fifo",0777); //创建一个命名管道
if(res==0)   //创建成功则打印输出
printf("FIFO created\n");
exit(EXIT_SUCCESS);   
}

(2)运行结果:
在这里插入图片描述
在这里插入图片描述
3.访问命名管道
(1))消费者
读空 FIFO 文件:$cat < /tmp/my_fifo
(2)生产者
向 FIFO 写数据(必须另外开一个终端执行如下命令)
$ echo “Hello,world” > /tmp/my_fifo

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值