命名管道Linux
管道是

毫不相关的进程进程间通信::命名管道
管道
首先自己要用用户层缓冲区,还得把用户层缓冲区拷贝到管道里,(从键盘里输入数据到用户层缓冲区里面),然后用户层缓冲区通过系统调用(write)写到管道里,然后再通过read系统调用,被对方(读端)读取,就要从管道拷贝到读端,然后再显示到显示器上。
mkfifo命名管道
1号手册是指令,。2号系统调用接口

创建一个管道,p开头就是命名管道,并不会直接刷新到磁盘中,实际是个符号

这样会阻塞

这样会显示出来(先输入左边的,再输入右边的就会显示),左右两边是两个进程

>>追加写入的方式,但空间一直是0



所以这就是文件里大小一直是0的原因 
你怎么知道打开的是同一个文件


正好符合前提

所以要创建两个可执行程序,各自跑各自的,创建一个common是为了方便使用头文件
client是客户 server是服务者



makefile中一下运行两个程序

mkfifo,用程序的方式创建管道,第一个参数是要创建的这个管道在那个路径下叫什么名字,也就是要保持唯一性的那些点,第二个是创建一个管道
这里是3号手册是函数。

返回 -1创建失败

创建一个共享文件
./myfifo

server.cc和client.cc想看到同一个文件,包含上头文件就可以了
这里先用server控制管道文件

创建管道失败了设置为1 ,如果失败了就exit(1)

谁控制的先运行运行谁就好了
make一下生成两个可执行程序,因为是server控制的,所以要先运行server

运行后就会多一个myfifo命名管道

命名管道的删除
想删除这个myfifo用unlink(成功返回0 ,失败返回-1)
命令行删除
![]()
代码也可以删(成功返回0 ,失败返回-1),头文件是unistd.h
创建完文件,5秒后就删除了

思路

用到了open

打开管道文件,第二个参数是只进行读取

enum中

fd<0打开失败了

服务端读取数据

客户端,只要用就行
第二个参数就是打开文件为了写入的


用户输入完成以后,就要发送输入的消息到另一端

打开顺序一定
然后打开的顺序就一定了,先打开server,然后再打开另一个cc
先打开服务端,会阻塞在这里,然后再打开客户端,进行输入

右边输入啥,左边就会有啥

无法输入空格问题(getline)
但有一个问题就是cin没法输入空格,,要用到getline

会发现一个问题,客户端退出了,服务端还没退出
客户端退出,会read到0,所以服务端(读端)也要退出
改正

sever端

等待写入方式打开后,自己才会打开文件,向后执行,open阻塞了!
优化一下


写成进程池的样子


日志
创建一个新文件

用到了可变参数(形参实例化是从右到左)
可变参数必须右至少一个具体的参数
举个例子:步骤:s指向可变部分
这里的sum第一个参数是几个数求和的意思,传不同的类型不可以的,因为上面va_arg里已经写死了

开始写日志,level日志等级

先定义时间,time,时间戳


ctime
头文件


打印具体年月日
年是从1900年开始的


年月日时分秒

vsnprint
vsnprint,跟不带v的区别就是,去除了...换成了可变参数部分

把日记等级转换成字符串风格,所有有可能的地方都需要返回

改进
va_start(s,format),用format修饰s的指向,上面的sum是(s,n),类似
这里要用c_str,因为返回的是string

用完以后再用end

这里是往显示器打印的,这里要*3,以为%s和%s中间有几个空格,空间不够


把这里修改一下,打开失败的话

这样就形成日志了
![]()

打印最后一行就是正常打开

这里也改一下

测试,先./server,然后会阻塞,然后./client,就会打印出,logmessage里的信息
为啥./client之前不打印
因为等待写入方式打开后,自己才会打开文件,向后执行,open阻塞了!

往文件里打印(上面是往屏幕打印)
先把这些内容全放在Log,日志类

分类
1:向屏幕打印
2:向一个文件打印
3:分类打印
打印格式printMethod

这里构造默认往屏幕去印

析构

打印方式也改一下



打印单个
以0666的权限打开这个文件

打印多个文件(添加一下level)


实现一下

优化一下


以后再打印日志就不用这样打了

这样就可以了,要记住先创建一个Log对象

这样以后就写入一个文件了,写入log.txt

这样就把日志分类了

结果

但是日志文件这么多太混乱了
这样操作后就统一进入一个文件了



makefile也修改一下,先把path定义的log目录创建一下

日志放入一个文件测试结果:
日志分类测试结果:


log.hpp里头文件

优化一下调用
然后修改一下server.cc


client.cc
#include "common.hpp"
#include "log.hpp"int main()
{int fd = open(FIFO_FILE,O_WRONLY);if(fd < 0){perror("open");exit(FIFO_OPEN_ERR);}string line;while(true){cout<< "Please Enter@ ";// cin>> line;getline(cin, line);write(fd, line.c_str(),line.size());}close(fd);return 0;
}
common.hpp
#pragma noce
#include<iostream>
#include<vector>
#include<string>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include<fcntl.h>
#include<stdio.h>
using namespace std;#define FIFO_FILE "./myfifo"
#define MODE 0664 //用于设置文件的权限,0664代表着8进制写法,4是其他用户可读不可写enum
{FIFO_CREATE_ERR = 1,FIFO_DELETE_ERR,FIFO_OPEN_ERR
};class Init
{
public:Init(){//创建管道int n = mkfifo(FIFO_FILE,MODE);if(n == -1){perror("mkfofi");exit(FIFO_CREATE_ERR);}}~Init(){//删除命名管道int m = unlink(FIFO_FILE);if(m == -1){perror("unlink");exit(FIFO_DELETE_ERR);} }
};
log.hpp
#pragma noce
#include <stdarg.h>
// #include "common.hpp"
#include <iostream>
#include <stdio.h>
#include<string.h>//strerror(errno)头文件
#include<stdlib.h>
using namespace std;#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4 // 致命的//打印方式
#define Screen 1 //屏幕
#define Onefile 2 //一个文件
#define Classfile 3 //多个文件#define LogFile "log.txt" class Log
{
public:Log(){printMehod = Screen;path = "./log/";}void Enable(int method){printMehod = method;}string levelToString(int level){switch (level){case Info:return "Info";case Debug:return "Debug";case Warning:return "Warning";case Error:return "Error";case Fatal:return "Fatal";default:return "";}return "";}// void logmessage(int level, const char *format, ...)// {// time_t t = time(nullptr);// struct tm *ctime = localtime(&t);// char leftbuffer[1024];// snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),// ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);// va_list s;// va_start(s, format);// char rightbuffer[1024];// vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);// va_end(s);// // 格式:默认部分+自定义部分// char logtxt[1024 * 3];// snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);// //cout << logtxt << endl; // 暂时打印// printLog(level, logtxt);// }void operator()(int level, const char* format, ...){time_t t = time(nullptr);struct tm *ctime = localtime(&t);char leftbuffer[1024];snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);va_list s;va_start(s, format);char rightbuffer[1024];vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);va_end(s);// 格式:默认部分+自定义部分char logtxt[1024 * 3];snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);//cout << logtxt << endl; // 暂时打印printLog(level, logtxt);}void printLog(int level, const string &logtxt){switch(printMehod){case Screen:cout<< logtxt <<endl;break;case Onefile:printOneFile(LogFile, logtxt);//"log.txt" break;case Classfile:printClassFile(level, logtxt);break;default:break;}}void printOneFile(const string &logname, const string &logtxt){// "./log/" "log.txt"string _logname =path + logname;int fd = open(_logname.c_str(), O_WRONLY|O_CREAT|O_APPEND, 0666);if(fd < 0) return;write(fd, logtxt.c_str(), logtxt.size());close(fd);}void printClassFile(int level, const string &logtxt){string filename = LogFile;//"log.txt" filename += ".";//"log.txt." filename += levelToString(level); //log.txt.Debug/Waring/FatalprintOneFile(filename, logtxt);}~Log(){}
private:int printMehod;string path;
};
makefile
.PHONY:all
all:client server
server:server.ccg++ -o $@ $^ -g -std=c++11mkdir log
client:client.ccg++ -o $@ $^ -g -std=c++11
.PHONY:clean
clean:rm -f server client
server.cc
#include "common.hpp"
#include "log.hpp"int main()
{//logmessage(Info, "hello");//创建管道Init init;Log log;//log.Enable(Onefile);log.Enable(Classfile);// //创建管道// int n = mkfifo(FIFO_FILE,MODE);// if(n == -1)// {// perror("mkfofi");// exit(FIFO_CREATE_ERR);// }// sleep(5);//打开管道int fd = open(FIFO_FILE,O_RDONLY);if(fd < 0){//log.logmessage(Fatal, "error string:%s,error code:%d",strerror(errno), errno);//优化后log(Fatal, "error string:%s,error code:%d",strerror(errno), errno);exit(FIFO_OPEN_ERR);}// log.logmessage(Info, "server open file done,error string:%s,error code:%d",strerror(errno), errno);// log.logmessage(Warning, "server open file done,error string:%s,error code:%d",strerror(errno), errno);//优化后log(Info, "server open file done,error string:%s,error code:%d",strerror(errno), errno);log(Warning, "server open file done,error string:%s,error code:%d",strerror(errno), errno);//......//开始通信while(true){char buffer[1024] = {0};int x = read(fd, buffer, sizeof(buffer));if(x > 0){buffer[x] = 0;cout<< "client say# " << buffer <<endl;}else if(x == 0){//log.logmessage(Debug, "sclient quit too!,error string:%s,error code:%d",strerror(errno), errno);//优化后log(Debug, "sclient quit too!,error string:%s,error code:%d",strerror(errno), errno);//cout<< "client quit too!\n" <<endl;break;}else break;}close(fd);// //删除命名管道// int m = unlink(FIFO_FILE);// if(n == -1)// {// perror("unlink");// exit(FIFO_DELETE_ERR);// }return 0;
}
相关文章:
命名管道Linux
管道是 毫不相关的进程进程间通信::命名管道 管道 首先自己要用用户层缓冲区,还得把用户层缓冲区拷贝到管道里,(从键盘里输入数据到用户层缓冲区里面),然后用户层缓冲区通过系统调用(write)写…...
【ios】---swift开发从入门到放弃
swift开发从入门到放弃 环境swift入门变量与常量类型安全和类型推断print函数字符串整数双精度布尔运算符数组集合set字典区间元祖可选类型循环语句条件语句switch语句函数枚举类型闭包数组方法结构体 环境 1.在App Store下载Xcode 2.新建项目(可以先使用这个&…...
【AUTOSAR 基础软件】PduR模块详解(通信路由)
文章包含了AUTOSAR基础软件(BSW)中PduR模块相关的内容详解。本文从AUTOSAR规范解析,ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解PduR这一基础软件模块。文中涉及的ISOLAR-AB配置以及模块相关代码都是依托于ETAS提供的…...
[控制理论]—差分变换法与双线性变换法的基本原理和代码实现
差分变换法与双线性变换法的基本原理和代码实现 1.差分变换法 差分变换法就是把微分方程中的导数用有限差分来近似等效,得到一个与原微分方程逼近的差分方程。 差分变换法包括后向差分与前向差分。 1.1 后向差分法 差分变换如下: d e ( t ) d t e…...
【JavaEE】——多线程常用类
阿华代码,不是逆风,就是我疯 你们的点赞收藏是我前进最大的动力!! 希望本文内容能够帮助到你!! 目录 引入: 一:Callable和FutureTask类 1:对比Runnable 2:…...
Cilium-实战系列-(二)Cilium-Multi Networking-多网络
一、Cilium必要开启的功能 1、enable-multi-network 2、ipam模式选择:multi-pool 二、涉及的CRD资源 1、 ciliumpodippools.cilium.io *通过Cilium管理节点上的pod cidr.网络分为主网络和第二网络。 *主网络的 ciliumpodippools.cilium.io default根据配置文件默认生成的。 …...
springboot自动配置
自动配置的核心就在SpringBootApplication注解上,SpringBootApplication这个注解 底层包含了3个注解,分别是: SpringBootConfiguration ComponentScan EnableAutoConfiguration EnableAutoConfiguration这个注解才是自动配置的核心,它 封…...
mock数据,不使用springboot的单元测试
业务代码 package com.haier.configure.service.impl;import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.haier.common.util.RequestUtil; import com.haier.configure.entity.Langua…...
【pytorch】pytorch入门5:最大池化层(Pooling layers )
文章目录 前言一、定义概念 缩写二、参数三、最大池化操作四、使用步骤总结参考文献 前言 使用 B站小土堆课程 一、定义概念 缩写 池化(Pooling)是深度学习中常用的一种操作,用于降低卷积神经网络(CNN)或循环神经网…...
职场上的人情世故,你知多少?这五点一定要了解
职场是一个由人组成的复杂社交网络,人情世故在其中起着至关重要的作用。良好的人际关系可以帮助我们更好地融入团队,提升工作效率,甚至影响职业发展。在职场中,我们需要了解一些关键要素,以更好地处理人际关系…...
Python | Leetcode Python题解之第456题132模式
题目: 题解: class Solution:def find132pattern(self, nums: List[int]) -> bool:candidate_i, candidate_j [-nums[0]], [-nums[0]]for v in nums[1:]:idx_i bisect.bisect_right(candidate_i, -v)idx_j bisect.bisect_left(candidate_j, -v)if…...
【重学 MySQL】五十四、整型数据类型
【重学 MySQL】五十四、整型数据类型 整型类型TINYINTSMALLINTMEDIUMINTINT(或INTEGER)BIGINT 可选属性UNSIGNEDZEROFILL显示宽度(M)AUTO_INCREMENT注意事项 适合场景TINYINTSMALLINTMEDIUMINTINT(或INTEGER࿰…...
查看 Git 对象存储中的内容
查看 Git 对象存储中的内容 ls -C .git/objects/<dir>ls: 列出目录内容的命令。-C: 以列的形式显示内容。.git/objects/<dir>: .git 是存储仓库信息的 Git 目录,objects 是其中存储对象的子目录。<dir> 是对象存储目录下的一个特定的子目录。 此…...
Redis 中热 Key 的判定及其解决方案
引言 Redis 作为高效的内存数据库,常用于缓存、消息队列等场景。随着数据量和并发量的增加,某些数据的访问频率会远远高于其他数据,这些被频繁访问的 Key 被称为 热 Key。热 Key 问题是 Redis 应用中常见的性能瓶颈之一,它可能导…...
elasticsearch创建索引
1对比关系型数据库,创建索引就等同于创建数据库 在postman中,向ES服务器发PUT请求 显示已经创建成功了 http://192.168.1.108:9200/shopping 请求方式get http://192.168.1.108:9200/shopping 请求全部的index的url地址 get 请求 http://192.168.1.10…...
【STM32单片机_(HAL库)】4-2-1【定时器TIM】定时器输出PWM实现呼吸灯实验
1.硬件 STM32单片机最小系统LED灯模块 2.软件 pwm驱动文件添加定时器HAL驱动层文件添加GPIO常用函数定时器输出PWM配置步骤main.c程序 #include "sys.h" #include "delay.h" #include "led.h" #include "pwm.h"int main(void) {HA…...
计算机网络:物理层 —— 信道复用技术
文章目录 信道信道复用技术信道复用技术的作用基本原理常用的信道复用技术频分复用 FDM时分复用 TDM波分复用 WDM码分复用 CDM码片向量基本原理 信道 信道是指信息传输的通道或介质。在通信中,信道扮演着传输信息的媒介的角色,将发送方发送的信号传递给…...
期权懂|期权交易涨跌幅限制会随时调整吗?
本期让我懂 你就懂的期权懂带大家来了解,期权交易涨跌幅限制会随时调整吗?有兴趣的朋友可以看一下。期权小懂每日分享期权知识,帮助期权新手及时有效地掌握即市趋势与新资讯! 期权交易涨跌幅限制会随时调整吗? 涨跌幅…...
阿里面试: RocketMQ如何实现每秒上十万QPS的超高吞吐量读取的?
这玩意儿表面看上去挺牛逼,但其实背后的逻辑和套路,在咱们开发里见过的那些招数,都能找到影子。 今天小北和大家一起系统化的梳理梳理一遍,让大家功力猛增,吊打面试官。 1. 消息存储:巧妙利用顺序写 先说…...
web:js原型污染简单解释
1. 什么是对象? 在 JavaScript 中,对象是一种包含属性和方法的数据结构。你可以把对象想象成一个存储键值对的容器。每个键(key)都有一个对应的值(value),这个值可以是数据或者函数。 let per…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关
在水泥厂的生产流程中,工业自动化网关起着至关重要的作用,尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关,为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多,其中不少设备采用Devicenet协议。Devicen…...


