首页 > 系统相关 >进程间的通信(管道)

进程间的通信(管道)

时间:2024-06-04 21:33:43浏览次数:26  
标签:buffer pipefd 通信 管道 进程 匿名 include

进程间的通信(管道)

进程间的通信(Inter-Process Communication,IPC) 是指在不同进程之间传递或交换信息。这些进程可以是运行在同一台计算机上,也可以是通过网络连接的不同计算机上的。由于不同的进程拥有不同的内存空间,因此不能通过简单地直接访问对方的内存空间来实现信息的传递或共享,需要通过一些特殊的方法来实现。

管道

  1. 匿名管道(Anonymous Pipe)
    • 匿名管道是Linux中最基本的管道类型,它没有名字,通常用于父进程和子进程之间的通信。
    • 当使用pipe()系统调用时,会创建一个匿名管道。这个系统调用返回两个文件描述符:一个用于写(通常是pipefd[1]),另一个用于读(通常是pipefd[0])。
    • 父进程和子进程分别通过这两个文件描述符进行读写操作。
    • 匿名管道是半双工的,即数据只能在一个方向上流动。
  2. 命名管道(Named Pipe 或 FIFO)
    • 命名管道也被称为FIFO(First In First Out),它有一个名字,并允许无亲缘关系的进程之间进行通信。
    • 使用mkfifo命令或mknod命令可以创建命名管道。
    • 与匿名管道不同,命名管道是持久的,即使创建它们的进程已经终止,它们仍然存在,直到被显式删除。
    • 命名管道可以是阻塞的或非阻塞的,这取决于进程如何打开它们。

匿名管道代码测试例

/*******************************************************************
*
*	file name:	fifo_text1.c
*	author	 :  [email protected]
*	date	 :  2024/06/01
*	function :  创建了一个匿名管道,测试子进程向匿名管道写入数据,父进程读取匿名管道中的数据,以实现进程间
*				的通信
* 	note	 :  None
*
*	CopyRight (c)  2023-2024   [email protected]  All Right Reseverd 
*
* *****************************************************************/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
  
int main() {  
    int pipefd[2]; // 定义文件描述符数组,pipefd[0]用于读,pipefd[1]用于写  
  
    // 创建匿名管道  
    if (pipe(pipefd) == -1) {  
        perror("pipe");  
        exit(EXIT_FAILURE);  
    }  
  
    // 创建子进程  
    pid_t pid = fork();  
  
    if (pid == -1) {  
        // 创建子进程失败  
        perror("fork");  
        exit(EXIT_FAILURE);  
    }  
  
    if (pid == 0) {  
        // 子进程  
        close(pipefd[0]); // 关闭读端  
  
        // 向管道写入数据  
        const char *message = "Hello from child process!\n";  
        write(pipefd[1], message, strlen(message));  
  
        close(pipefd[1]); // 关闭写端  
        exit(EXIT_SUCCESS);  
    } else {  
        // 父进程  
        close(pipefd[1]); // 关闭写端  
  
        // 从管道读取数据  
        char buffer[1024];  
        ssize_t bytesRead = read(pipefd[0], buffer, sizeof(buffer) - 1);  
        if (bytesRead > 0) {  
            buffer[bytesRead] = '\0'; // 添加字符串终止符  
            printf("Received from child: %s", buffer);  
        }  
  
        close(pipefd[0]); // 关闭读端  
        wait(NULL); // 等待子进程结束  
    }  
  
    return 0;  
}

命名管道代码示例

/*******************************************************************
*
*	file name:	fifi_text2.c
*	author	 :  [email protected]
*	date	 :  2024/06/01
*	function :  将数据写入有名管道中的数据实现进程间的通信
* 	note	 :  None
*
*	CopyRight (c)  2023-2024   [email protected]  All Right Reseverd 
*
* *****************************************************************/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include <sys/stat.h>  
#include <sys/types.h>  
#include <unistd.h>  
  
#defined FIFO_PATH   "./fifo1"
int main() {  
  
    // 创建有名管道  
    if (mkfifo(fifo_path, 0666) == -1) {  
        perror("mkfifo");  
        exit(EXIT_FAILURE);  
    }  
  
    // 打开有名管道以写入数据  
    int fd = open(fifo_path, O_WRONLY);  
    if (fd == -1) {  
        perror("open");  
        exit(EXIT_FAILURE);  
    }  
  
    // 写入数据到有名管道  
    const char *message = "Hello, Named Pipe!";  
    ssize_t bytes_written = write(fd, message, strlen(message) + 1);  
    if (bytes_written == -1) {  
        perror("write");  
        exit(EXIT_FAILURE);  
    }  
  
    // 关闭管道  
    close(fd);  
  
    // 删除有名管道(可选)  
    unlink(fifo_path);  
  
    return 0;  
}
/*******************************************************************
*
*	file name:	pipe_text.c
*	author	 :  [email protected]
*	date	 :  2024/06/1
*	function :  读取有名管道中的数据实现进程间的通信
* 	note	 :  None
*
*	CopyRight (c)  2023-2024   [email protected]  All Right Reseverd 
*
* *****************************************************************/
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <fcntl.h>  
#include <unistd.h>  
  
#define MAX_BUF 256  
#defined FIFO_PATH   "./fifo1" 
int main() {  
    // 打开有名管道以读取数据  
    int fd = open(fifo_path, O_RDONLY);  
    if (fd == -1) {  
        perror("open");  
        exit(EXIT_FAILURE);  
    }  
  
    // 读取数据  
    char buffer[MAX_BUF];  
    ssize_t bytes_read = read(fd, buffer, MAX_BUF - 1);  
    if (bytes_read == -1) {  
        perror("read");  
        exit(EXIT_FAILURE);  
    }  
  
    // 确保字符串以null终止  
    buffer[bytes_read] = '\0';  
  
    // 打印读取到的数据  
    printf("Received: %s\n", buffer);  
  
    // 关闭管道  
    close(fd);  
  
    return 0;  
}

管道是Linux中一种简单而有效的进程间通信机制,它允许进程之间通过内存中的管道进行数据的读写操作,匿名管道经常用于父进程和子进程之间的通信,特别是当子进程需要执行一些操作并将结果返回给父进程时,而命名管道可以用于更复杂的场景,例如多个进程之间的数据交换或服务器与客户端之间的通信。

如果代码用法有什么问题,请将问题发至网易邮箱 [email protected],作者将及时改正,欢迎与各位老爷交流讨论。

麻烦三连加关注!!!!

比心

标签:buffer,pipefd,通信,管道,进程,匿名,include
From: https://www.cnblogs.com/zkbklink/p/18231793

相关文章

  • 多播通信
    网络编程代码:/***************************************************************************************filename:1.c*author: [email protected]*date:2024/06/04*function: 多播通信*note :none*CopyRight(c)202......
  • 09-进程和计划任务管理
    9.1查看和控制进程9.1.1查看进程1.ps命令pS命令是Linux操作系统中最为常用的进程查看工具,主要用于显示包含当前运行的各进程完整信息的静态快照。通过不同的命令选项,可以有选择性地查看进程信息。命令作用a显示当前终端下的所有进程信息,包括其他用户的进程。u......
  • 网络编程练习题---利用UDP协议实现组播通信
    目录题目解析代码实现题目解析由于该题需要实现组播通信,所以我们需要将套接字文件句柄设置为组播属性,并将需要通信的用户端IP地址,加入组中。由于组播通信需要实现一对多发送消息,所以还需要将套接字文件句柄的广播属性一并开启。由于该题实现过程使用到了线程相关函数接口,所......
  • Linux学习笔记6 进程角度看内存泄露
    一,从进程角度看堆区内存申请与释放问题1,c语言中的内存泄漏内存溢出:申请内存时,没用足够的内存可以使用。 内存泄露:严格来说,只有对象不会再被程序用到了,但是GC又不能回收它们的情况,才叫内存泄漏                宽泛的讲,实际情况中很多时候一些不太好的实践......
  • 进程和任务管理器
    一、查看和控制进程1.1ps命令(1)ps命令——查看静态的进程统计信息(ProcessesStatistic)PIDTTYTIMECMD1579pts/100:00:00bash1730pts/100:00:00psPID:进程IDTTY  (进程id)TTY:表明该进程在哪个终端上运行。“?”表示未知或不需要终端。TIME:该进程占用的CPU时间C......
  • 进程任务管理
    一.  查看和控制进程    程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程是在CPU及内存中处于动态执行的计算机程序。在Linux操作系统中,每个程序启动后可以创建一个或多个进程。列如,提供Web服务的httpd程序,当有大量用户同时访问Web页面时......
  • 线程池 + 回调 (进程赤用法类似)
    importosimportthreadingimporttimefromconcurrent.futuresimportThreadPoolExecutorfromfunctoolsimportwrapsThreadPool=ThreadPoolExecutor(max_workers=10)defthread_executor(a):print("Iamslave.Iamworking.Iamgoingtosleep3......
  • linux进程和计划任务管理
    一、查看和控制进程程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程是在 CPU 及内存中处于动态执行状态的计算机程序。在 Linux 操作系统中,每个程序启动后可以创建一个或多个进程。例如,提供 Web 服务的 httpd 程序,当有大量用户同时访问Web......
  • Linux进程和计划任务管理
    查看和控制进程程序是保存在外部存储介质(如硬盘)中的可执行机器代码和数据的静态集合,而进程 是在CPU 及内存中处于动态执行状态的计算机程序。查看进程了解系统中进程的状态是对进程进行管理的前提,使用不同的命令工具可以从不同的 角度查看进程状态。1.ps命令——查看......
  • Vue3中实现父子组件通信
    Vue3中实现父子组件通信父传子父组件给子组件绑定属性,子组件内部提供props选项接收setup语法糖下局部组件无需注册可以直接使用//父组件中<scriptsetup>importSonComfrom''constmessage=ref('thisisfather')</script><template><SonCom:messgae="mess......