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

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

无名管道

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

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

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

有名管道****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;
}
相关推荐
朝新_1 分钟前
【优选算法】第一弹——双指针(上)
算法
APItesterCris7 分钟前
构建弹性数据管道:利用淘宝商品 API 进行流式数据采集与处理
linux·数据库·windows
九河云13 分钟前
TOS + 数字孪生:集装箱码头的智能进化密码
大数据·服务器·网络·数据库·数字化转型
艾莉丝努力练剑23 分钟前
【C++STL :stack && queue (一) 】STL:stack与queue全解析|深入使用(附高频算法题详解)
linux·开发语言·数据结构·c++·算法
代码or搬砖24 分钟前
文件上传阿里云OSS以及本地图片服务器搭建
服务器·阿里云·云计算
悟能不能悟32 分钟前
dcpatchscan.exe这是什么
运维·服务器
kyle~38 分钟前
计算机系统---CPU的进程与线程处理
linux·服务器·c语言·c++·操作系统·计算机系统
CoovallyAIHub39 分钟前
ICLR 2026 惊现 SAM 3,匿名提交,实现“概念分割”,CV领域再迎颠覆性突破?
深度学习·算法·计算机视觉
wanhengidc43 分钟前
云手机 流畅运行
运维·服务器·安全·游戏·智能手机
NiKo_W1 小时前
Linux 进程通信——基于责任链模式的消息队列
linux·服务器·消息队列·责任链模式·进程通信