进程间通信的方式简单解析————管道

本人最近学习了进程间通信,并看了一些博文,然后结合书籍根据自己的理解写了这篇文章。

1. 管道

函数原型:经由参数fd返回两个文件描述符:fd[0]为读,fd[1]为写。fd[1]的输出是fd[0]的输入。
#include <unistd.h>
	int pipe(int fd[2]);
局限性:
(1)历史上,它是半双工的,某些系统提供全双工管道,即其可移植性并不好。
(2)它只能在具有公共祖先的两个进程间使用。
示例代码:
#include <stdio.h>
#include <unistd.h>
#include <error.h>
#include <string.h>

int main(){
    int pipe_fd[2];
    int ret = pipe(pipe_fd);//类似两个文件指针,针对管道中的读(0)和写(1)
    if(ret == -1)
    {
        printf("创建管道失败,错误码是:%d,%d\n",error,strerror(error));
        return 0;
    }   

    pid_t pid = fork();//创建子进程

    if(pid < 0)
    { 
        printf("创建子进程错误\n");
        return 0;
    }else if(pid == 0)
    {  //子进程的操作
        close(_pipe[0]);  // 关闭读通道
        int i = 0;
        char sendbuf[BUFSIZ];
        while( i < 20){
            scanf("%s", sendbuf);
            write(pipe_fd[1], sendbuf, strlen(sendbuf));
            sleep(2);
            i++;
        }   
    }else
    {    //进入父进程,从子进程读取数据
        close(pipe_fd[1]);  //关闭写通道
        char recv[BUFSIZ];
        while(1){
            memset(recv, 0, sizeof(recv));
            int length= read(pipe_fd[0], recv, sizeof(recv));                                                                                                                                                                                          
            if(strstr(recv, "quit") != 0)
            { 
                printf("退出程序\n");
                exit(0);
            }   
            printf("message:%s. length:%d.\n", recv, length);
        }   

        if(waitpid(pid, NULL, 0) < 0)
        {  //避免父进程与子进程冲突,让子进程先执行
            return 0;
        }   
    }   
    return 0;
}
运行结果:

在这里插入图片描述

2. 命名管道(FIFO)

函数原型:
#include<sys/stat.h>
	int mkfifo(const char *path, mode_t mode);
	int mkfifoat(int fd, const char *path, mode_t mode);
参数信息:
(1)参数fd为文件描述符。
(2)参数path为路径名。
(3)mode参数指定文件的访问权限位。
FIFO的用途:
(1)shell命令使用FIFO将数据从一条管道传送到另一条时,无需创建中间临时文件。
(2)C/S应用程序中,FIFO用作汇聚点,在二者之间传递数据。
示例代码:fifo-read.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>                                                                                                                                                                                                                                  
#include <sys/types.h>
#include <sys/stat.h>

#define _PATH_ "/tmp/file.fifo"

int main(){
    int fd = open(_PATH_, O_RDONLY);//以只读的权限打开文件
    if(fd < 0){ 
        printf("打开失败\n");
        return 0;
    }   
    char recv[BUFSIZ];
    while(1){
        memset(recv, 0, sizeof(recv));//字符串清零
        int ret = read(fd, recv, sizeof(recv));
        if(strstr(recv, "quit") != 0){ //判断接收到的字符是否是quit
            printf("退出程序\n");
            exit(0);
        }   
        printf("message:%-20s. length:%d\n", recv, ret);
    }   

    close(fd);//关闭文件
    return 0;
}
运行结果:

在这里插入图片描述

fifo-write,c
#include <unistd.h>                                                                                                                                                                                                                                  
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>

#define _PATH_ "/tmp/file.fifo"

int main(){
    int ret = mkfifo(_PATH_, 0666);//创建管道文件
    if(ret == -1){
        printf("创建管道失败\n");
        exit(0);
    }   
    int fd = open(_PATH_, O_WRONLY);//以只写的权限打开文件
    if(fd < 0){ 
        printf("打开失败\n");
        exit(0);
    }   
    char buf[BUFSIZ];
    while(1){
        memset(buf, 0, strlen(buf));//字符串清零
        printf("please input the string:");
        scanf("%s", buf);
        int ret = write(fd, buf, strlen(buf));//写数据
        if(ret < 0){ 
            printf("写出错\n");
            break;
        }   
        if(strstr(buf, "quit") != 0){ 
            break;
        }   
    }   

    close(fd);//关闭文件
    unlink(_PATH_);//删除管道文件
    return 0;
}
运行结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值