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

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

无名管道

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

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

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

有名管道****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;
}
相关推荐
To_OC5 小时前
LC 51 N 皇后:我以为难的是回溯,结果栽在了对角线下标
javascript·算法·leetcode
2401_841495646 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
Yana.nice6 小时前
Linux 只保留 30 天内日志(find命令删除日志文件)
linux·运维·chrome
吳所畏惧9 小时前
宝塔面板Redis密码修改指南:SSH命令修改 vs 面板UI界面修改,哪个更靠谱?
运维·服务器·数据库·redis·缓存·ssh
DFT计算杂谈9 小时前
无 Root 权限在 Tesla K80 零门槛部署 DeepSeek 大模型
linux·服务器·网络·数据库·机器学习
爱刷碗的苏泓舒10 小时前
PPP-AR 中的参考星选取:数学原理、评价指标与切换处理
算法·gnss·模糊度固定·ppp-ar·星间单差·参考星·卫星端偏差
维天说10 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json
Zhang~Ling10 小时前
从 fopen 到 struct file:从零开始拆解 Linux 文件 I/O
linux·运维·服务器
DeeplyMind10 小时前
Linux 深入 per-VMA lock:Linux 缺页路径如何摆脱 mmap_lock
linux·per-vma lock