进程间通信方法一:管道:pipe()、fifo

管道的实现原理是内核使用循环队列机制,借助内核缓冲区(4K)实现
管道的局限性:

  1. 由于管道采用半双工的通信方式,所以数据只能在一个方向上流动,要不读要不写(读、写只能占一样)
  2. 数据一旦被读走,便不在管道中留存,只能读取一次
  3. 只能在有公共祖先的进程间使用管道

创建匿名管道

  • 应用于有血缘关系的进程间通信

pipe函数

函数原型

int pipe(int pipefd[2]);

  • 返回值
    成功返回0;失败返回-1
  • 函数调用成功后,返回两个文件描述符(r/w),无需手动open,但需手动close
    pipefd[0]:读文件描述符
    pipefd[1]:写文件描述符

例子

  • 父子进程间通信
    • 父进程写:要关闭父进程的读数据端,防止父进程自己把数据再次读走
    • 父进程读:要关闭父进程的写数据端
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
//管道只要规定好一端读,一端写即可,哪方读哪方写自己规定
//此处子进程读,父进程写
int main(){
    int fd[2];
    int ret = pipe(fd);
    pid_t pid = fork();
    if(pid == -1){
        perror("子进程创建失败");
        exit;
    }else if(pid == 0){
        close(fd[1]);//子进程读数据,关闭写文件的文件描述符,防止子进程再往里面写数据
        char buf[1024];//此处读数据,没用循环是因为写的内容一次性可以读完
        ret = read(fd[0],buf,sizeof(buf));
        printf("读到的数据为;%s",buf);//将读到的数据打印到屏幕上
        write(STDOUT_FILENO,buf,ret);//将读到的数据打印到屏幕上
    }else{
        close(fd[0]);//父进程写数据,关闭读数据的文件描述符,防止子进程再自己把读走
        char *str = "hello world\n";
        write(fd[1],str,strlen(str));
    }
    return 0;
}

创建有名管道fifo

特点

  • 有名管道
  • 在磁盘上有一个管道文件
  • 伪文件,在磁盘大小永远为0
  • 在内核中有一个对应的缓冲区
  • 半双工的通信方式

应用场景

  • 用于非血缘关系进程之间的通信

创建方式

  • 命令

    mkfifo 管道名

  • 函数

    int mkfifo(const char* pathname, mode_t mode);

    • 参数

      pathname:管道文件名

      mode:管道文件的权限

例子

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
int main(){
    //判断管道文件是否存在,不存在创建
    int ret = access("myfifo",F_OK);
    if(ret == -1){
        ret = mkfifo("myfifo",0666);
        if(ret == -1){
            perror("管道文件fifo创建失败");
            exit(1);
        }
    }

    int fd = open("myfifo",O_WRONLY);
    if(fd == -1){
        perror("文件打开失败");
        exit(2);
    }
    char buf[] = "hello world\n";
    while(1){
        write(fd,buf,sizeof(buf));
        sleep(1);
    }
    close(fd);
    return 0;
}

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
int main(){
    int fd = open("myfifo",O_RDONLY);
    if(fd == -1){
        perror("文件打开失败");
        exit(1);
    }else if(fd == 0){
        printf("%d\n",fd);
    }
    char buf[1024];
    int len;
    while(1){
        len = read(fd,buf,sizeof(buf));
        write(STDOUT_FILENO,buf,len);
       // sleep(1);
    }
    close(fd);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值