【操作系统】操作系统课后作业-聊天程序

无名管道与有名管道的区别

无名管道

它是半双工的,具有固定的读端和写端。

只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

不是普通的文件,不属于其他任何文件系统,并且只存在于内存中。

有名管道****FIFO

FIFO可以在无关的进程之间交换数据。

FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。

思路

父进程负责写,子进程负责读。

FIFO1负责存储用户a发出的消息,

FIFO2负责存储用户b发出的消息。

代码

chat_a.c

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
 
int main(){
    pid_t pid = fork();
    if (pid > 0)
    {
        //a的父进程写FIFO1
        char *fifo1 = "./fifo1";
        //判断fifo1是否存在
        int ret = access(fifo1, F_OK);
        if (ret == -1){
            //文件不存在,需要创建
            ret = mkfifo(fifo1, 0664);
            if (ret == -1){
            	//创建失败 
                perror("mkfifo error");
                exit(-1);
            }
        }
        //文件fifo1存在,以只写方式打开
        int fdw = open(fifo1, O_WRONLY);
        if (fdw == -1)
        {
            perror("open error");
            exit(-1);
        }
        printf("a:successfully opened fifo1\n");
        //循环写入数据
        char buf[256];
        while (1){
            memset(buf, 0, sizeof(buf));
            //获取标准输入的数据
            fgets(buf, sizeof(buf), stdin);
            //写数据到fifo1
            int len = write(fdw, buf, strlen(buf));
            if (len == -1){
                perror("write error");
                break;
            }
            printf("\n");
        }
        close(fdw);
    }
    else if (pid == 0)
    {
        //a的子进程读FIFO2
        char *fifo2 = "./fifo2";
        //判断FIFO2是否存在
        int ret = access(fifo2, F_OK);
        if (ret == -1)
        {
            //文件不存在,需要创建
            ret = mkfifo(fifo2, 0664);
            if (ret == -1)
            {
            	//创建失败
                perror("mkfifo error");
                exit(-1); 
            }
        }
        //文件FIFO2存在,以只读方式打开
        int fdr = open(fifo2, O_RDONLY);
        if (fdr == -1)
        {
            perror("open error");
            exit(-1);
        }
        printf("a:successfully opened fifo2\n");
        //循环读数据
        char buf[256];
        while (1)
        {
            memset(buf, 0, sizeof(buf));
            int len = read(fdr, buf, sizeof(buf));
            if (len <= 0)
            {
                perror("read");
                break;
            }
            printf("b: %s\n", buf);
        }
        close(fdr);
    }
    return 0;
}

chat_b.c

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
 
int main(){
    pid_t pid = fork();
    if (pid > 0){
        //b的父进程写FIFO2
        char *fifo2 = "./fifo2";
        //判断文件fifo2是否存在
        int ret = access(fifo2, F_OK);
        if (ret == -1)
        {
            //文件不存在,需要创建
            ret = mkfifo(fifo2, 0664);
            if (ret == -1)
            {
                perror("mkfifo error");
                exit(-1);
            }
        }
        //文件fifo2存在,以只写方式打开
        int fdw = open(fifo2, O_WRONLY);
        if (fdw == -1)
        {
            perror("open error");
            exit(-1);
        }
 
        printf("b:successfully opened fifo2\n");
        //循环写入数据
        char buf[256];
        while (1)
        {
            memset(buf, 0, sizeof(buf));
            //获取标准输入的数据
            fgets(buf, sizeof(buf), stdin);
            //写数据到fifo2
            int len = write(fdw, buf, strlen(buf));
            if (len == -1)
            {
                perror("write error");
                break;
            }
            printf("\n");
        }
        close(fdw);
    }
    else if (pid == 0)
    {
        //b的子进程读FIFO1
        char *fifo1 = "./fifo1";
        int ret = access(fifo1, F_OK);
        if (ret == -1)
        {
            //文件不存在,需要创建
            ret = mkfifo(fifo1, 0664);
            if (ret == -1)
            {
                perror("mkfifo error");
                exit(-1); 
            }
        }
        //文件FIFO1存在,以只读方式打开
        int fdr = open(fifo1, O_RDONLY);
        if (fdr == -1)
        {
            perror("open error");
            exit(-1);
        }
        printf("b:successfully opened fifo1\n");
        // 循环读数据
        char buf[256];
        while (1)
        {
            memset(buf, 0, sizeof(buf));
            int len = read(fdr, buf, sizeof(buf));
            if (len <= 0)
            {
                perror("read");
                break;
            }
            printf("a: %s\n", buf);
        }
        close(fdr);
    }
 
    return 0;
}
相关推荐
松涛和鸣2 分钟前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
Jay Kay11 分钟前
GVPO:Group Variance Policy Optimization
人工智能·算法·机器学习
Epiphany.55623 分钟前
蓝桥杯备赛题目-----爆破
算法·职场和发展·蓝桥杯
简单中的复杂28 分钟前
【避坑指南】RK3576 Linux SDK 编译:解决 Buildroot 卡死在 host-gcc-final 的终极方案
linux·嵌入式硬件
YuTaoShao1 小时前
【LeetCode 每日一题】1653. 使字符串平衡的最少删除次数——(解法三)DP 空间优化
算法·leetcode·职场和发展
茉莉玫瑰花茶1 小时前
C++ 17 详细特性解析(5)
开发语言·c++·算法
wVelpro1 小时前
如何在Pycharm 2025.3 版本实现虚拟环境“Make available to all projects”
linux·ide·pycharm
cpp_25011 小时前
P10570 [JRKSJ R8] 网球
数据结构·c++·算法·题解
cpp_25011 小时前
P8377 [PFOI Round1] 暴龙的火锅
数据结构·c++·算法·题解·洛谷
uesowys1 小时前
Apache Spark算法开发指导-Factorization machines classifier
人工智能·算法