【IO】Day7

该文展示了如何用C语言通过创建有名管道(mkfifo)实现两个进程(A.c和B.c)之间的通信。每个进程都包含父进程和子进程,子进程负责写入数据到管道,父进程则从管道读取并显示数据。当输入quit时,通信结束。

使用管道实现AB两个进程的相互通信(提示:每个程序都可以使用多进程、多线程)

create.c

        创建2个有名管道

#include <myhead.h>

int main(int argc, const char *argv[])
{
	//创建2个有名管道文件,权限为0664
	if(mkfifo("./myfifo1",0664) == -1)
	{
		perror("mkfifo1 create error");
		return -1;
	}
	if(mkfifo("./myfifo2",0664) == -1)
	{
		perror("mkfifo2 create error");
		return -1;
	}

	//使用函数阻塞主函数
	getchar();

	//删除管道文件
	system("rm myfifo1");
	system("rm myfifo2");

	return 0;
}

A.c

#include<myhead.h>

int main(int argc, const char *argv[])
{

    pid_t pid = fork();

    if(pid<0)
    {
        perror("fork error");
        return -1;
    }else if(pid == 0)                     
    {
         //子进程负责向文件1中中写数据
        int fd;       //文件描述符
        char buf[128] ="";

        //只写形式打开有名管道文件1
        if((fd = open("./myfifo1", O_WRONLY)) == -1)
        {
            perror("open error");
            return -1;
        }

        //循环往管道中写数据
        while(1)
        {
            fgets(buf, sizeof(buf), stdin);
            //清掉'\n'
            buf[strlen(buf) - 1] = '\0';

            //将输入写入管道中
            write(fd, buf, strlen(buf));

            //如果输入的是quit
            if(strcmp(buf, "quit") == 0)
            {
                break;
            }

        }

        //关闭文件
        close(fd);
        exit(EXIT_SUCCESS);
    }else                            
    {
         //父进程负责从文件1中读数据
    
        int fd;    //定义文件描述符
        char buf[128] = "";

        //只读形式打开文件2
        if((fd = open("./myfifo2", O_RDONLY)) == -1)
        {
            perror("open error");
            return -1;
        }

        while(1)
        {
            memset(buf, 0, sizeof(buf));

            //从管道中读取数据
            read(fd, buf, sizeof(buf));

            if(strcmp(buf, "quit") == 0)
            {
                break;
            }

            printf("%s\n", buf);    //将内容打印在终端上
        }

        close(fd);          //关闭文件
        wait(NULL);

    }
    
    return 0;
}

B.c

#include<myhead.h>

int main(int argc, const char *argv[])
{

    pid_t pid = fork();

    if(pid<0)
    {
        perror("fork error");
        return -1;
    }else if(pid == 0)          
    {
 	//子进程负责向myfifo2管道中进行写数据
        int fd;       //文件描述符
        char buf[128] ="";

        //打开有名管道文件
        if((fd = open("./myfifo2", O_WRONLY)) == -1)
        {
            perror("open error");
            return -1;
        }

        //循环往管道中写数据
        while(1)
        {
            fgets(buf, sizeof(buf), stdin);
            //清掉'\n'
            buf[strlen(buf) - 1] = '\0';

            //将输入写入管道中
            write(fd, buf, strlen(buf));
            //如果输入的是quit
            if(strcmp(buf, "quit") == 0)
            {
                break;
            }

        }

        //关闭文件
        close(fd);
        exit(EXIT_SUCCESS);
    }else                     
    {
	//父进程负责从myfifo1管道文件中读取数据
  
        int fd;        //定义文件描述符
        char buf[128] = "";

        //打开文件
        if((fd = open("./myfifo1", O_RDONLY)) == -1)
        {
            perror("open error");
            return -1;
        }

        while(1)
        {
            memset(buf, 0, sizeof(buf));

            //从管道中读取数据
            read(fd, buf, sizeof(buf));

            if(strcmp(buf, "quit") == 0)
            {
                break;
            }

            printf("%s\n", buf);    //将内容打印在终端上
        }

        close(fd);             //关闭文件
        wait(NULL);
    }
    
    return 0;
}

运行结果如下(打开3个终端分别运行):

ubuntu@ubuntu:71pipe$ gcc create.c -o c.out
ubuntu@ubuntu:71pipe$ gcc A.c -o a.out
ubuntu@ubuntu:71pipe$ ./a.out 
hello wrold
this is a perfect summer
end
quit
ubuntu@ubuntu:71pipe$ 
ubuntu@ubuntu:71pipe$ gcc B.c -o b.out
ubuntu@ubuntu:71pipe$ ./b.out 
hello wrold
this is a perfect summer
end
quit

ubuntu@ubuntu:71pipe$ 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值