• 多进程编程(二):管道


    进程间通信(InterProcess Communication,IPC)

    主要通信方式:

    • 管道
      1、匿名管道(pipe
      2、有名管道(FIFO
    • 消息队列
    • 共享内存
    • 信号量
    • 信号
    • 套接字(Socket

    管道

    匿名管道

    前一章提到了一个shell命令:ps -ef | grep demo
    这里的 | 其实就是一个管道,shell创建了两个进程来分别执行 ps -efgrep demo,并将前一个的输出,作为输入给到第二个。
    在这里插入图片描述

    特点:
    1、管道是一个在内核内存中维护的缓冲区,这个缓冲区的存储能力是有限的,不同操作系统的大小不一定相同(Linux64位系统下其大小是4k),可以使用shell命令:ulimit -a查看
    2、管道拥有文件的特质:读操作、写操作,但是没有文件实体。
    3、管道只能承载无格式字节流以及缓冲区大小受限
    4、通过管道传递的数据是顺序的,读取与写入的顺序保持一致
    5、传递是单向的,如果想要双向通信,就要创建两个管道,也就是要么父进程写入,子进程读取;要么父进程读取,子进程写入
    6、只能在具有公共祖先的进程之间使用(父子进程,兄弟进程,具有亲缘关系的进程)

    函数

    #include <unistd.h>
    int pipe(int pipefd[2]);
    - pipefd[0] : 管道读取端
    - pipefd[1] : 管道写入端
    - 返回值:
    	创建成功返回 0
    	创建失败返回 -1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    举例:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
    
    	// 创建管道
    	int pipe_fd[2] = {0};
    	int res_p = pipe(pipe_fd);
    	if (res_p == 0) {
    		printf("pipe create success\n");
    	} else {
    		perror("pipe");
    	}
    
    	// 创建子进程
    	pid_t res = fork();
    
    	// 父进程写入数据
    	if (res > 0) 
    	{	
    		close(pipe_fd[0]); // 关闭读取端
    		printf("Parent: \n");
    		char buf_w[] = "Hello, world";
    		write(pipe_fd[1], buf_w, strlen(buf_w));
    	} 
    	else if (res == 0)  // 子进程读取数据
    	{
    		close(pipe_fd[1]); // 关闭写入端
    		printf("Child: \n");
    		char buf_r[100];
    		read(pipe_fd[0], buf_r, 100);
    		printf("%s\n", buf_r);
    	} 
    	else 
    	{
    		perror("fork");
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    有名管道

    匿名管道只能用于具有亲缘关系的进程间通信。为了客服这个缺点,提出了有名管道(FIFO)。
    有名管道(FIFO)不同于匿名管道之处在于它提供了一个路径名与之关联以FIFO的文件形式存于文件系统中,并且其打开方式与打开一个普通文件是一样的,这样即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够通过FIFO相互通信。

    函数:

    #include <sys/types.h>
    #include <sys/stat.h>
    int mkfifo(const char *pathname, mode_t mode);
    - pathname: FIFO文件的路径 或者是 想要保存的路径
    - mode: 权限
    - 返回值:
    	成功:0
    	失败:-1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    一旦创建了FIFO,就可以使用 open 打开它,常见的 I/O 函数都可用于 FIFO

  • 相关阅读:
    JS中iframe如何却写面包屑功能
    “外卖员的时间没有程序员值钱”:读过书就把自己当人上人?得电
    GPT-4o
    centos8安装jenkins,gitee+webHook配置
    理解npm run dev 和 npm run serve的区别
    ICML-2022 | 强化学习论文清单(附链接)
    微信小程序隐私授权
    anchor box --学习笔记
    项目问题——Error during artifact deployment. See server log for details.
    python pandas query用法
  • 原文地址:https://blog.csdn.net/Sir666888/article/details/125458796