进程间通信《管道篇》

本文详细介绍了进程间通信的两种管道形式:无名管道和有名管道。无名管道适用于亲缘进程间通信,特点包括无文件名、半双工、非持久性等。有名管道则支持任意进程间通信,具有全双工、可持久化等特性。通过函数调用来创建和使用这两种管道。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一 、管道(Pipe、Fifo)

        1. 无名管道 pipe:适用于亲缘关系进程间的、一对一的通信。

        2. 有名管道 fife   :  适用于任何进程间的一对一,多对一的通信。       

二、 无名管道(pipe)

        1. 管道是一种文件,无名管道没有文件的名字。

        2. 无名管道的特点:

                1) 因为没有具体的文件名字,所以没有在磁盘里形成具体的文件。

                2) 虽然是文件类型,但是不能用 lseek 定位。

                3) 退出程序后,程序内的管道资源会被释放,下次运行需要再创建。

                4) 只能用于亲缘进程(父子,兄弟,爷孙)

                5) pipe 是在fork之前创建的,(当有四个端口时,两个读,两个写,才能实现双向通信)。

                6)无名管道是在内核创建出来的

                7) 属于半双工通信

                8) 不能用open打开

                9)写操作没有原子性。

        3. 函数使用

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>


#define MSG_LENGTH  20   // 宏定义
int main()
{
    // 创建管道
	int pipefd[2] = {0};
	int pipe_ret = pipe(pipefd);
	if(pipe_ret == -1)
	{
		perror("pipe");
		exit(-1);
	}
	
    // 创建父子进程
	int pid = fork();
	if(pid == -1)
	{
		perror("fork");
		exit(-1);
	}
	else if(pid == 0)                //子进程
	{
		char msg_data[MSG_LENGTH];
		memset(msg_data,0,MSG_LENGTH);
		printf("请输入发给父亲的信息:");
		scanf("%s",msg_data);
		
		/*发送*/
		write(pipefd[1],msg_data,strlen(msg_data));
		
	}
	else                            // 父进程
	{
		char msg_data[MSG_LENGTH];
		memset(msg_data,0,MSG_LENGTH);

        /*接收*/
		read(pipefd[0],msg_data,MSG_LENGTH);
		printf("儿子说:%s\n",msg_data);
	}
	
	/*共享区域*/
	close(pipefd[0]);
	close(pipefd[1]);
	
	if(pid > 0)
		wait(NULL);
		
	exit(0);
}

 三 、 有名管道(fife)

        1. 基本概念:

                有名管道:有名字的管道,所有的具体文件,都是在闪存里面存放的

        2. 特点:

                1) 血缘 和 非血缘都可以用

                2) 可用 open 打开,

                3) 不能用 lseek 定位

                4) 写操作有原子性

                5) 全双工

                6) 退出程序后,有名管道可一直使用,直到把文件删除

        2. 实现代码

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_PATH "/tmp/dante_fifo"

int main()
{
    //先判断管道存不存在

    if(access(FIFO_PATH,F_OK))
    {
        umask(0000);
        mkfifo(FIFO_PATH,0777);
    }

    int fifo_fd = open(FIFO_PATH,O_RDWR);
    if(fifo_fd == -1)
    {
        perror("open");
        return -1;
    }

    char msg_data[10];
    while(1)
    {
        memset(msg_data,0,10);
        printf("请输入要发给小红的信息");
        scanf("%s",msg_data);

        write(fifo_fd,msg_data,strlen(msg_data));
    }

    close(fifo_fd);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值