mkfifo()命名管道-FIFO客户端 服务端模拟。*System V消息队列、信号量(信号灯)。

@bit::Shadow
✧(≖ ◡ ≖✿

目录

*C中的FILE与PCB的关系?

子进程初创时图解

命名管道

mkfifo()创建

unlink()删除管道文件

☆☆☆命名管道关闭的正确顺序:

模拟服务端与客户端交互:

服务端

客户端

MP4效果演示

注意点:

ERR_EXIT异常退出宏定义

[" \ "必须加?](#“ \ ”必须加?)

匿名管道与命名管道的总结

[System V前瞻](#System V前瞻)

[链接🔗System V共享内存内核级详解下篇](#链接🔗System V共享内存内核级详解下篇)

[System V消息队列(queue)](#System V消息队列(queue))

[System V信号量(Semaphoes)](#System V信号量(Semaphoes))

PV机制(原子性"二态性"):

信号量相关术语

临界区与非临界区的对比

"锁"区分临界区非临界区图解:

[System V信号量接口](#System V信号量接口)


*C中的FILE与PCB的关系?

概念 所在位置 管理者
FILE 结构体 用户空间 C 标准库(glibc)
file 结构体(内核) 内核空间 内核
文件描述符表 PCB 内(内核空间) 内核

子进程初创时图解

子进程初创:

部分独立,部分指向原内容区。

命名管道

原理:利用路径的唯一性,创建"伪文件"(命名管道)标识,来关联不同进程,实现进程间通信。

命名管道是一个特殊的文件,以权限符"p"标识,由于管道通信数据先进先出的性质常以FIFO来指示命名管道。

mkfifo()创建

指令:

bash 复制代码
mkfifo fifo

代码:

cpp 复制代码
int mkfifo(const char* pathname, mode_t mode);

pathname:要创建文件的路径+名字。

mode:权限设置。 0666

返回值:

-1:失败,错误码被设置

0:正常创建。

unlink()删除管道文件

指令:

bash 复制代码
unlink #管道文件名

代码:

cpp 复制代码
int unlink(const char* pathname);

命名管道分作读取端与写端,当读取端打开写入端没有打开时或写端打开读端没有打开时均会阻塞。阻塞在open()或read()

☆☆☆命名管道关闭的正确顺序:

cpp 复制代码
close(fd);      // 1. 先关闭文件描述符 不再占用此文件
unlink("fifo"); // 2. 再删除文件 删除目录项 文件引用计数-1到0时删除

模拟服务端与客户端交互:

实现服务端(Server)到客户端(Client)的信息发送"I'm father",客户端读取输出。

服务端

1.创建命名管道fifo

2.打开管道并写入

3.关闭fd删除命名管道

cpp 复制代码
//Server.cc
int Sever() {
    int n = mkfifo("fifo", 0666);
    if(n == -1)
    {
        perror("错误");
        exit(1);
    }
    // 打开 写入"I'm father"
    int fd = open("fifo", O_WRONLY);
    if(fd == -1)
    {
        perror("open\n");
        exit(1);
    }
    printf("打开成功准备写入");
    // 写入
    std::string s = "I'm father";
    write(fd, s.c_str(), s.size());
    printf("写入完毕\n");

    // 关闭
    close(fd);
    //删除
    unlink("fifo");
    return 0;
}

客户端

1.打开、读取。

2.输出关闭。

cpp 复制代码
//Client.cc
int Client() { 
    //打开
    int fd = open("fifo", O_RDONLY);
    if(fd == -1)
    {
        perror("open fail");
        exit(1);
    }
    // 读取
    char s[64] = {0};
    int n = read(fd, s, 63);
    if(n == -1)
    {
        perror("read failed");
        exit(1);
    }
    // 输出
    printf("客户端读取结果:%s\n", s);
    // 关闭
    close(fd);

    return 0; 
}

MP4效果演示

服务端写入信息,客户端读取

注意点:

1.mkfifo时若已经存在则失败。

2.读端open时未创建则失败。

3.写后要关闭+删除。

ERR_EXIT异常退出宏定义

由于以后及及现在的检验原理激增所以定义此宏就十分有必要。

使用do { ...... }while(0)循环的目的是使此宏得以适应各种逻辑语句内。像循环语句,条件语句等等。

cpp 复制代码
#define ERR_EXIT(str) \
do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)

" \ "必须加?

是的因为宏是全替换。

匿名管道与命名管道的总结

匿名管道通过int pipe(int fds2);创建一fds0与fds1分别作管道的读端和写端 并分别占用该进程接下来的两个文件描述符fd,配合fork()使用以分支父子进程,若要实现单向通信,可以父进程读端关闭子进程写端 关闭。匿名管道是文件流无文件本身与磁盘分隔

命名管道通过int mkfifo(const char* pathname, mode_t mode);实现具有名字"伪文件"管道的创建,其打破了"相邻进程间通信"的限制,操作完全类似于文件操作但unlink(int fd);删除目录项。


System V前瞻

System V(通常读作 "System Five")是 Unix 操作系统历史上最重要的法定版本之一,由 AT&T 贝尔实验室于 1983 年首次发布。它不仅奠定了现代商业 Unix 的基础,其许多设计理念和机制至今仍深深影响着 Linux 和 macOS 等现代操作系统。

System V信号量(Semaphoes):用于多个进程对共享资源的访问,解决同步与互斥问题。++仅作简要介绍。++

System V消息队列:允许进程以消息链表(队列)的形式异步发送和接受数据块。++仅作简要介绍。++

链接🔗System V共享内存内核级详解下篇

System V消息队列(queue)

System V信号量(Semaphoes)

解决System V中进程间数据安全问题。

信号量介绍:

"信号量"又称"信号灯",是描述对资源(内存、共享内存)预订情况的量,若可用资源已经耗尽,则申请(再次预订)会失败并阻塞挂起。

"资源耗尽"的信号灯依据------PV机制(荷兰语:Proberen,尝试/申请 ,Verhogen,增加/释放)。

PV机制(原子性"二态性"):

例原本int sem = 16;

申请维护sem--,原子操作 P操作。

退出归还sem++,原子操作 V操作。

例,若sem = 1;仅有"1"和"0"两种状态,称为"二元信号量"。

信号量相关术语

临界资源:被保护起来的共享资源。

临界区:每个进程中访问临界资源的那段"代码"

非临界区:不涉及共享资源(如:全局变量、共享内存、硬件设备等)操作的代码区域

互斥:一种制约关系。当一个进程进入临界区使用资源时 ,其他资源必须等待,直到该进程退出临界区。(银行自用ATM机)

临界区与非临界区的对比

| 特性 | 临界区 (Critical Section) | 非临界区 (Non-critical Section) |
| 资源访问 | 访问共享资源(如修改公共变量、写日志文件) | 只访问局部变量或进行独立计算 |
| 并发冲突 | 多个线程同时进入会导致**数据竞争(Data Race)**或死锁 | 多个线程同时执行互不影响,完全安全 |
| 同步控制 | 必须加锁(如 MutexSemaphore)限制访问 | 无需任何锁,线程可以并发现行 |

执行时间 应当越短越好(减少其他线程的等待时间) 往往包含大量的业务逻辑、计算或I/O
"锁"区分临界区非临界区图解:
System V信号量接口

创建 int semget(key_t key, int nsems, int semflg);

控制 int sectl(int semid, int semnum, int cmd,......);

int semop(int semid ,struct sembuf* sops, size_t nsops);

感谢支持,持续更新

欢迎关注

相关推荐
daad7771 小时前
继续记录SITL的大循环
linux
h_a_o777oah1 小时前
2026 蓝桥杯软件 C++B组 国赛比赛经历及备赛建议
c++·经验分享·算法·蓝桥杯
zfoo-framework1 小时前
kotlin中体会到一些比较好用的点
android·开发语言·kotlin
赵谨言1 小时前
基于C#的在线编码与自动化测试全栈Web平台的设计与实现
开发语言·前端·c#
酉鬼女又兒1 小时前
零基础入门计算机网络:点对点协议PPP、媒体接入控制基本概念、静态划分信道技术、CSMA/CD与CSMA/CA协议全面详解
服务器·网络·网络协议·计算机网络·职场和发展·求职招聘·媒体
maosheng11461 小时前
基于AI 文本生成的自动化Linux 运维文档系统
运维·人工智能·自动化
牛油果子哥q1 小时前
C++六大默认成员函数深度精讲:构造/析构/拷贝/赋值/移动构造/移动赋值、编译器生成规则、深浅拷贝终极坑点与工程实战
开发语言·c++
智塑未来1 小时前
2025-2026年具身智能机器人自动化程度综合评测:五大品牌自研大模型与操作系统全对比
运维·机器人·自动化
AI_零食1 小时前
奶茶大数据运维表 - 鸿蒙PC Electron框架技术实现详解
运维·前端·华为·electron·开源·harmonyos·鸿蒙