【Linux系统篇】:从匿名管道到命名管道--如何理解进程通信中的管道?
✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨
✨ 个人主页:余辉zmh–CSDN博客
✨ 文章所属专栏:Linux篇–CSDN博客
文章目录
- 一.进程通信
- 进程通信概念
- 进程通信目的
- 进程通信分类
- 二.管道
- 匿名管道
- 1.原理实现
- 2.接口函数与编码实现
- 3.管道的4种读写情况
- 4.管道的5种特征
- 命名管道
- 1.原理实现
- 2.指令和接口函数
- 3.示例--编码实现
- 两种管道总结对比
- **1. 创建方式与可见性**
- **2. 使用范围**
- **3. 生命周期**
- **4. 打开与阻塞行为**
- **5. 权限与安全性**
- **6. 双向通信实现**
一.进程通信
进程通信概念
进程通信(Inter-Process Communication, IPC
)是操作系统提供的机制,允许两个或多个独立的进程实现数据层面的交互。
因为进程独立性的存在,导致进程之间进行通信的成本比较高;而通信成本,主要就是用来打破进程独立性。
1.进程间通信的本质,必须让不同的进程看到同一份“资源”!这个“资源”,本质上就是一个特定形式的内存空间,相当于两个独立的进程共享一个特殊的内存空间,然后进行通信。
2.至于这个“资源”由谁提供?肯定是由操作系统提供。
那为什么不是进行通信的两个进程中的其中一个呢?
假设这个“资源”是其中一个进程提供,这个“资源”本质上是属于提供的这个进程的,还是由该进程独有,而进程之间具有独立性,一旦这个“资源”由其中某个进程提供,就会破环该进程的独立性,所以这个“资源”一定是个第三方空间,由操作系统提供的。
3.这个“资源”由操作系统提供,当进程访问这个空间进行通信时,本质就是访问操作系统!而进程代表的是用户,相当于是用户在访问操作系统;用户访问操作系统只能通过系统调用来实现。
这个“资源”从创建到使用再到释放都是通过系统调用接口来实现!
4.一般操作系统会有一个独立的通信模块:IPC
通信模块—隶属于文件系统;而进程间通信是有标准的—system V
和posix
(现如今的两种通信标准),如果没有统一的标准,就无法实现不同设备间的通信。
进程通信目的
-
数据传输:
一个进程需要将他的数据发送给另一个进程。
-
资源共享:
多个进程之间共享同样的资源。
-
通知事件:
一个进程需要向另一个或一组进程发送消息,通知他发生了某种事件(比如进程终止时通知父进程)。
-
进程控制:
有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时直到他的状态改变。
进程通信分类
- 管道:匿名管道和命名管道
- System V IPC:
System V
消息队列;System V
共享内存;System V
信号量 - Posix IPC:消息队列;共享内存;信号量;互斥量;条件变量;读写锁
二.管道
管道是Unix中最古老的进程间通信的形式。
一个文件可以被多个进程所访问,文件本身就是一种公共资源,如果一个进程写,另一个进程读,就可以实现进程间通信。管道就是一种基于文件形式的通信方式。
其中管道分为匿名管道和命名管道。
匿名管道
1.原理实现
文件无论是读还是写,都要先将磁盘上的内容加载到文件对应的页缓冲区。而对于通信来说,只需要两个进程间通过管道文件来实现数据传输即可,并不需要将数据刷新到磁盘上。这种文件属于内核级文件,不考虑页缓冲区和磁盘之间的刷新。
每个进程都有一个文件描述符表,表示的是该进程打开的文件描述列表。当父进程通过fork创建子进程后,子进程要拷贝父进程的内核数据结构,所以子进程会有一份和父进程相同的文件描述符表。
但是对于父进程打开的文件,并不会为子进程创建一份相同的文件再打开(文件属于文件系统,和进程管理不相连,进程的内核数据结构可以拷贝,但是文件不会再拷贝一份)。
而父子进程的文件描述符表中的内容相同,存放的都是相同的struct file*
,所以最后要指向相同的文件(当其中某个进程关闭该文件时,因为其他进程还在使用,引用计数不为0,所以不会关闭,并不影响另一个)。
如果操作系统给父进程创建一个管道文件(内核级文件),最后子进程通过继承也会和父进程指向同一个内核级文件,这样父子进程就可以看到同一份“资源”,就可以实现进程间通信了。
但是如果父进程以读方式打开管道文件,子进程继承父进程后,也会是读方式打开,并不是写方式打开。而进程间通信,肯定是一个读,另一个写;所以这样两个都读就不能实现进程间通信。
所以父进程会以读和写方式打开管道文件两次,子进程继承下来也会以读和写方式打开两次。读和写方式打开两次,就会为该进程创建两个strcut file
,但是两个struct file
指向的是同一个文件页缓冲区,只是读写方式不同而已。
创建子进程后,父子进程指向两个相同的struct file*
,最后也就指向同一个页缓冲区,父子进程都有读写方式,但是只能进行单向通信。
父进程读取,子进程写入;父进程就要关闭写端,子进程就要关闭读端。
子进程读取,父进程写入;子进程就要关闭写端,父进程就要关闭读端。
注意是哪个不用关哪个!
如果想要进行双向通信,可以建立多个管道;但是不能在一个管道中双向通信。
2.接口函数与编码实现
pipe
函数是Unix/Linux系统中的一个关键系统调用,用于创建管道以实现进程间通信。
1.函数原型:
#include <unistd.h>int pipe(int fd[2]);
- 成功返回0,失败返回-1,并设置
errno
。 - 参数
fd[2]
是一个输出型参数,系统为进程创建管道后,会将读写方式打开的两个文件描述符填入到参数fd[2]
中,函数调用结束后带出来,让用户使用;其中fd[0]
为读端,fd[1]
为写端。
2.单向通信:
- 管道是单向通信的,数据从写端流向读端。
- 若需双向通信,需创建两个管道。
3.文件描述符管理:
- 创建管道后,父进程通过fork函数创建子进程,子进程会继承父进程的文件描述符。
- 通信时,应关闭不需要的端,避免资源泄露或阻塞。
编码实现
单向通信(子进程写入,父进程读取):
#include<iostream>
#include<unistd.h>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<cstring>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;#define N 2
#define NUM 1024void Write(int wid){string str = "hello, I am child";pid_t pid = getpid();int number = 0;//创建一个应用缓冲区char buffer[NUM];while (true){//缓冲区当字符串使用,每次清空buffer[0] = 0;//格式化写入到缓冲区中---字符串处理snprintf(buffer, sizeof(buffer), "%s-%d-%d", str.c_str(), pid, number++);//发送/写入给父进程write(wid, buffer, strlen(buffer)); //注意这里不用+1,只是写入内容,不考虑最后的'\n'//每次休眠1秒sleep(1);}
}void Read(int rid){//创建一个应用缓冲区char buffer[NUM];while(true){buffer[0] = 0;ssize_t n = read(rid, buffer, sizeof(buffer));if(n>0){buffer[n] = '\0';cout << "father get a message[" << getpid() << "]:" << buffer << endl;}}
}int main(){int pipefd[N] = {0};int n = pipe(pipefd);if(n<0)return 1;// cout << "pipefd[0]: " << pipefd[0] << ", pipefd[1]: " << pipefd[1] << endl;// child-> w, father-> rpid_t id = fork();if(id < 0)return 2;if(id == 0){//child//关闭读端close(pipefd[0]);//IPC codeWrite(pipefd[1]);//关闭写端close(pipefd[1]);exit(0);}//father//关闭写端close(pipefd[1]);//IPC codeRead(pipefd[0]);//父进程回收子进程pid_t rid = waitpid(id, nullptr, 0);if(rid<0)return 3;// 关闭读端close(pipefd[0]);return 0;
}
3.管道的4种读写情况
-
1.读写端正常,管道如果为空,读端就要阻塞:
以上面演示的代码为例,让子进程写入时,每次休眠一秒,而父进程读取时没有限制,最后看到的现象就是父进程读取同样也是每间隔一秒读取到一次内容。
子进程每一秒写入一次,父进程读取完一次后,管道为空,父进程读端就会阻塞,等待子进程下一次的写入。
-
2.读写端正常,管道如果写满,写端就要阻塞:
让子进程每次写入时没有限制,父进程每次读取时先休眠五秒,最后看到的现象就是每次读取时都是读取到管道中的全部内容。
子进程每次写入没有限制,在父进程休眠的前5秒,子进程将管道中全部写满,此时父进程还没有进行读取,子进程写端就会阻塞,等待父进程将管道中的内容读取后才能继续写入。
-
3.读端正常,写端关闭,读端就会读到0,表示读取到文件末尾,不会被阻塞:
子进程每隔一秒写入一次,写入五次后关闭不在写入,写端关闭;父进程每隔一秒读取一次,读取5次后,之后再次读取每次都是读取到0;虽然子进程的写端关闭,但是父进程的读端并不会阻塞,依然在读取,只不过每次都是读取到0,表示读取到文件末尾。
如果读取到文件末尾后不想再继续读取,可以根据read函数的返回值设置对应的判断语句:
void Read(int rid){//创建一个应用缓冲区char buffer[NUM];while (true){//sleep(5);buffer[0] = 0;ssize_t n = read(rid, buffer, sizeof(buffer));if(n>0){buffer[n] = '\0';cout << "father get a message[" << getpid() << "]:" << buffer << endl;}//如果读取到文件末尾,就结束else if(n==0){cout << "father read file done" << endl;break;}else{break;}cout << n << endl;sleep(1);} }
-
4.写端正常写入,读端关闭,操作系统会杀掉正在写入的进程:
子进程写端正常写入,但是父进程读端读取5次后,关闭读端,此时子进程就没必要再继续写入了,因为没有其他进程来读取,操作系统不会做低效,浪费等类似工作的,如果做了,就是操作系统的bug;因此操作系统就会杀掉正在写入的子进程。
如何杀掉正再写入的进程?
通过信号来杀掉!
通过代码测试:子进程写端修改成每隔一秒写入一次:
父进程读端修改成读取5次后关闭:
父进程回收子进程后,输出子进程的退出信息:
最后看到的现象就是,子进程收到的异常信号为13,因为代码没有跑完,所以退出码为0。
4.管道的5种特征
1.对于匿名管道需要具有血缘关系的进程才可以进行进程间通信(比如父子进程,兄弟进程,爷孙进程),而这个管道是一个内核级别的文件,不需要有路径和文件名,因此又叫做匿名管道。
2.管道只能单向通信,不能双向通信,如果要双向通信,需要建立两个管道。
3.进程间通信时是会进程协同的(比如上面管道4种读写情况中的前两种),同步与互斥–用来保护文件的数据安全(后面讲解多线程的时候会讲解,现在只需了解即可)。
4.管道是面向字节流的(后面讲解网络部分会讲解,现在只需了解即可)。
5.管道是基于文件的,而文件的生命周期是随进程的,当进程结束后,系统会自动释放管道文件资源。
匿名管道补充内容:
匿名管道的其中一个应用场景就是指令中的管道|
!
测试:
父进程都是bash命令行解释器,是具有血缘关系的进程。
命名管道
匿名管道的一个限制就是只能在具有血缘关系(具有共同祖先)的进程间通信。如果想在不相关的进程之间进行通信,可以使用FIFO
文件来做这项工作,他经常被称为命名管道。
1.原理实现
对于两个不同的进程,如果想要进行通信,也是需要先看到同一份“资源”,也就是打开同一个文件。对于具有血缘关系的进程,通过继承可以打开同一个文件;而不相关的进程要想打开同一个一个文件,只能通过同路径下同一个文件名来实现。
路径+文件名具有唯一性,两个不相关的进程就可以根据不同的读写方式打开同一个文件,一个读,一个写,这样就可以实现进程间通信了。
对于两个不相关的进程打开同一个文件,在内核中,系统也是只打开一个文件(页缓冲区只有一个,但是struct file
有两个,一个以读方式打开,一个以写方式打开),和匿名管道通信的原理大致相同。
2.指令和接口函数
1.命名管道可以从命令行上创建/删除,命令行方法是使用下面这个命令:
# 创建
mkfifo filename# 删除
rm/unlink filename
2.命名管道可以从程序里创建/删除,相关函数:
#include <sys/types.h>
#include <sys/stat.h>// 创建
int mkfifo(const char *pathname, mode_t mode);
// 删除
int unlink(const char *pathname);
- 参数:
pathname
:FIFO文件(命名管道)的路径名。mode
:文件权限(八进制数字,比如0666;需结合进程的umask
值:0002,实际权限为mode & ~umask
。
- 返回值:
- 成功返回0,失败返回-1,并设置
errno
。
- 成功返回0,失败返回-1,并设置
特性:
-
文件系统中的可见性:
- FIFO文件会持久性在文件系统中(需手动删除)。
- 可通过指令
ls-l
查看,类型为p
(如:prw-r--r--
)。
-
阻塞行为:
默认情况下,打开FIFO时会阻塞,直到另一端也被打开:
其中一个进程以只读(
O_RDONLY
)模式打开,会阻塞直到另一个进程以写模式(O_WRONLY
)模式打开;其中一个进程以写模式(
O_WRONLY
)模式打开,会阻塞直到另一个进程以只读(O_RDONLY
)模式打开;
3.示例–编码实现
用命名管道实现server&client通信:
comm.hpp
文件:
通过一个Init
类封装命名管道的创建和删除
#pragma once
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <cerrno>
#include <cstring>
#include <fcntl.h>
#include <string>#define FIFO_FILE "./myfifo"
#define MODE 0664
#define SIZE 1024enum
{FILE_CREATE_ERR = 1,FILE_DELETE_ERR,FILE_OPEN_ERR,FILE_READ_ERR,
};class Init
{
public:Init(){// 创建管道int n = mkfifo(FIFO_FILE, MODE);if (n == -1){perror("mkfifo");exit(FILE_CREATE_ERR);}}~Init(){// 删除管道int m = unlink(FIFO_FILE);if (m == -1){perror("unlink");exit(FILE_DELETE_ERR);}}
};
server.cc
文件:
server进程用来读取client进程写入的信息
#include "comm.hpp"
using namespace std;int main(){Init init;// 打开管道int fd = open(FIFO_FILE, O_RDONLY);if(fd < 0){perror("open");exit(FILE_OPEN_ERR);}// 等待写入端打开文件之后,读取端才会打开文件,然后继续执行,否则会阻塞等待cout << "server open file done! " << endl;// 开始通信while(true){char buffer[SIZE];int x = read(fd, buffer, sizeof(buffer));if(x > 0){buffer[x] = 0;cout << "client say@ " << buffer << endl;}else if(x == 0){cout << "client quit, me too!" << endl;break;}else{perror("read");exit(FILE_READ_ERR);break;}}close(fd);return 0;
}
client.cc
文件:
client进程用来写入信息发送给server进程
#include "comm.hpp"
using namespace std;int main(){// 打开管道int fd = open(FIFO_FILE, O_WRONLY);if(fd < 0){perror("open");exit(FILE_OPEN_ERR);}cout<<"client open file done! "<<endl;// 开始通信string line;while (true){cout << "Please Enter# ";getline(cin, line);write(fd, line.c_str(), line.size());}close(fd);return 0;
}
实现效果:
当server进程以只读模式打开时会阻塞,直到client进程以写入模式打开:
两种管道总结对比
1. 创建方式与可见性
特性 | 匿名管道 | 命名管道 |
---|---|---|
创建方式 | 通过 pipe() 系统调用创建,返回两个文件描述符(读端 fd[0] 和写端 fd[1] )。 | 通过 mkfifo() 系统调用创建,生成一个 FIFO 文件(如 ./myfifo )。 |
可见性 | 仅存在于内存中,没有文件系统实体。 | 以文件形式存在于文件系统中,可通过 ls -l 查看(类型标记为 p )。 |
2. 使用范围
特性 | 匿名管道 | 命名管道 |
---|---|---|
通信范围 | 仅限具有亲缘关系的进程(如父子进程、兄弟进程)。 | 允许任意进程(即使无亲缘关系)通过文件名访问。 |
典型场景 | 简单的单向通信(如父子进程间传递数据)。 | 跨进程通信(如独立运行的进程间协作)。 |
3. 生命周期
特性 | 匿名管道 | 命名管道 |
---|---|---|
生命周期 | 随进程结束自动销毁。 | 需手动调用 unlink() 删除文件,否则持久存在于文件系统中。 |
数据持久性 | 数据仅存在于内核缓冲区中,进程结束后消失。 | 数据同样暂存于内核缓冲区,但文件名持久化。 |
4. 打开与阻塞行为
特性 | 匿名管道 | 命名管道 |
---|---|---|
打开行为 | 创建后两端(读/写)已同时存在,无需等待。 | 默认以阻塞模式打开: 以 O_RDONLY 打开会阻塞,直到有进程以 O_WRONLY 打开; 以 O_WRONLY 打开会阻塞,直到有进程以 O_RDONLY 打开。 |
关闭行为 | 一端关闭后,另一端读取会返回 EOF ,写入会触发 SIGPIPE 信号。 | 行为与匿名管道一致。 |
5. 权限与安全性
特性 | 匿名管道 | 命名管道 |
---|---|---|
权限控制 | 无文件系统权限,仅通过进程继承文件描述符共享。 | 受文件系统权限控制(如 mode 参数和 umask )。 |
安全性 | 仅能被创建管道的进程以及具有血缘关系的进程访问。 | 需确保文件名唯一且路径安全,避免冲突或恶意访问。 |
6. 双向通信实现
特性 | 匿名管道 | 命名管道 |
---|---|---|
双向通信 | 需创建两个管道(一个读一个写)。 | 同样需创建两个 FIFO 文件。 |
以上就是关于进程通信中管道的讲解,如果哪里有错的话,可以在评论区指正,也欢迎大家一起讨论学习,如果对你的学习有帮助的话,点点赞关注支持一下吧!!!
相关文章:
【Linux系统篇】:从匿名管道到命名管道--如何理解进程通信中的管道?
✨感谢您阅读本篇文章,文章内容是个人学习笔记的整理,如果哪里有误的话还请您指正噢✨ ✨ 个人主页:余辉zmh–CSDN博客 ✨ 文章所属专栏:Linux篇–CSDN博客 文章目录 一.进程通信进程通信概念进程通信目的进程通信分类 二.管道匿名…...
三、The C in C++
第三章主要讲解了 C 中继承自 C 语言的核心元素,包括函数创建、执行控制、操作符、数据类型、作用域、存储指示、复合类型创建等。 3.1 创建函数(Creating Functions) C允许函数重载,同名的函数可以根据参数类型和数量区分&…...
探索图像分类模型的 Flask 应用搭建之旅
最近深入研究了利用深度学习模型进行图像分类,并将其部署到 Flask 应用中的项目,过程中遇到了不少挑战,也收获了满满的知识,迫不及待想和大家分享一下。 一、项目背景与目标 在当今数字化的时代,图像数据呈爆炸式增长…...
OpenAI发布GPT-4.1系列模型——开发者可免费使用
OpenAI刚刚推出GPT-4.1模型家族,包含GPT-4.1、GPT-4.1 Mini和GPT-4.1 Nano三款模型。重点是——现在全部免费开放! 虽然技术升级值得关注,但真正具有变革意义的是开发者能通过Cursor、Windsurf和GitHub Copilot等平台立即免费调用这些模型。…...
自动化测试工具playwright中文文档-------14.Chrome 插件
介绍 注意 插件仅在以持久化上下文启动的 Chrome/Chromium 浏览器中工作。请谨慎使用自定义浏览器参数,因为其中一些可能会破坏 Playwright 的功能。 以下是获取位于 ./my-extension 的 Manifest v2 插件背景页面句柄的代码示例。 from playwright.sync_api imp…...
VGA显示
屏幕扫描形式 在回扫的过程中,电子枪不能发射电子,否则会影响荧光屏上既有图像的颜色,所以 回扫期间,需要进行行消隐,简单来说就是关闭电子枪。每行结束时,用行同步信号进行行 同步,图中从右上方向左下方的斜向虚线就是其回行扫示意图。 当整个屏幕的所有行都扫…...
微服务1--服务架构
系统架构 单体应用架构 特点:所有功能集中在一个应用中(如传统的 Spring Boot WAR 包)。 适用场景:小型项目、快速验证阶段。 优缺点: ✅ 开发简单,部署方便。 ❌ 扩展性差,技术栈耦合。 …...
鸿蒙应用元服务开发-Account Kit配置登录权限
一、场景介绍 华为账号登录是基于OAuth 2.0协议标准和OpenID Connect协议标准构建的OAuth2.0 授权登录系统,元服务可以方便地获取华为账号用户的身份标识,快速建立元服务内的用户体系。 用户打开元服务时,不需要用户点击登录/注册按钮&#…...
zg-docker详解与部署微服务实战与k8s
一. Docker课程 Docker简介 Docker是一个开源的容器引擎,有助于快速开发,docker更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 使用宿主机的网络:即使用宿主机的网段。 联合文件系统-一个镜像,启动了多个容器,对于镜像中的文件a,多个容器…...
【含文档+PPT+源码】基于Python的快递服务管理系统【
毕业作品基于Django和HTML的快递网站设计与实现 课程目标: 教你从零开始部署运行项目,学习环境搭建、项目导入及部署,含项目源码、文档、数据库、软件等资料 课程简介: 本课程演示的是一款基于Python的快递服务管理系统&#x…...
嵌入式WebRTC轻量化SDK压缩至500K-800K ,为嵌入式设备节省Flash资源
一、SDK轻量化的核心技术实现 1、WebRTC库裁剪与模块化设计 EasyRTC针对嵌入式设备的资源限制,对原生WebRTC库进行深度裁剪,仅保留核心通信功能(如信令管理、编解码、网络传输等),移除冗余组件(如部分调试…...
JAVA学习-Stream
Stream Stream也叫Stream流,是Jdk8开始新增的一套API (java.util.stream.*),可以用于操作集合或者数 组的数据。 优势: Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式 操作集合或者数…...
如何在同一个电脑配置多个jdk版本并随意切换
1.右键此电脑属性 2.点击高级系统配置 3.点击环境变量 4.进去后点击新建 变量名:JAVA_HOME_版本,来进行命名 变量值:jdk的路径即可,比如我的是D:\JAVA\JAVA11 5.创建完你所有的jdk版本之后接着新建 变量名:JAVA_HOME…...
网工_传输层协议概述
2025.02.19:网工老姜&小猿网学习笔记 第22节 传输层协议概述 2.1 进程之间的通信2.2 传输层的两个主要协议2.3 传输层的端口2.3.1 端口号 2.4 本章小结 2.1 进程之间的通信 前三层解决了数据从主机到主机的问题,也就是,我们现在已经可以把…...
《java面试宝典》之java多线程面试题
1:什么是线程? 轻量级的进程 2:线程的三个部分是? 处理机 代码 数据 3:为什么使用多线程 使UI响应更快 利用多处理器系统 简化建模 4:代码示例:Java中实现多线程的两种方式,包括如何…...
5款电脑健康状况监测软件
鲁大师:专业且免费,能检测电脑硬件配置,辨别硬件真伪,检查电脑病毒隐患。可一键清理系统垃圾,提升电脑性能。还能全程监护硬件状态,实时检测硬件温度变化,让用户轻松掌握电脑健康状况。360 安全…...
JWT令牌:实现安全会话跟踪与登录认证的利器
摘要:本文深入探讨了JWT令牌在实现会话跟踪和登录认证方面的应用,详细介绍了JWT令牌的概念、组成、生成与校验方法,以及在实际案例中如何通过JWT令牌进行会话跟踪和登录认证的具体实现步骤,为系统的安全认证机制提供了全面且深入的…...
uni-app/微信小程序接入腾讯位置服务地图选点插件
uni-app/微信小程序接入腾讯位置服务地图选点插件 0、常出现的错误及解决方法0.1插件未授权使用(见步骤1)0.2小程序类目不符合引用该类目插件的要求或主体类型不符合要求(见步骤1)0.3需要在app.json中声明permission scope.userLo…...
3款顶流云电脑与传统电脑性能PK战:START云游戏/无影云/ToDesk云电脑谁更流畅?
这里写目录标题 一、前言二、本地机器配置环境三、START云游戏/无影云/ToDesk云电脑配置对比3.1 START云游戏3.2 无影云个人版3.3 ToDesk云电脑 四、本地电脑与云电脑性能实战4.1 游戏场景体验4.1.1 本地电脑测试4.1.2 云电脑测试英雄联盟黑神话悟空其他游戏 4.2 主流设计场景体…...
WINUI——Background小结
在 WinUI/UWP XAML 中,Background(或其他颜色属性)支持 多种颜色表示方式,包括以下三种主流格式: 1. RGB 十六进制(不透明) 格式:#RRGGBB特点…...
公司内部自建知识共享的方式分类、详细步骤及表格总结,分为开源(对外公开)和闭源(仅限内部),以及公共(全员可访问)和内部(特定团队/项目组)四个维度
以下是公司内部自建知识共享的方式分类、详细步骤及表格总结,分为开源(对外公开)和闭源(仅限内部),以及公共(全员可访问)和内部(特定团队/项目组)四个维度&am…...
cursor AI编辑器的详细使用
以下是Cursor AI编辑器的详细使用介绍,涵盖核心功能、安装配置、使用技巧、高级应用及常见问题解决方案,结合了多个权威来源的实践指南和最新技术动态: 一、Cursor AI简介与核心功能 定位与架构 Cursor是基于Visual Studio Code(V…...
js逆向入门实战某某观察网响应数据解密
(base64解码 base64解码)地址:aHR0cHM6Ly93d3cuc3dndWFuY2hhLmNvbS9ob21lL2NpdHktZGV0YWlsP2NvZGU9MzEwMTAw 分析过程 1.抓数据包,发现响应数据是加密字符串。 2.对于这种回显数据解密,大概率通过拦截器实现,搜索intercepto…...
Ubuntu安装yum遇到Package ‘yum‘ has no installation candidate
环境说明 Window11,WSL2,Ubuntu24.04 错误描述 rootLAPTOP:~# apt-get install yum Reading package lists... Done Building dependency tree... Done Reading state information... Done Package yum is not available, but is referred to by anot…...
爱普生SG3225EEN低抖动差分晶振在网络通信的应用
在当今数字化时代,网络通信的飞速发展对数据传输的准确性、稳定性和高效性提出了极为严苛的要求。从 5G 通信网络的大规模部署,到数据中心的海量数据交换,再到智能家居系统的互联互通,每一个环节都离不开精准稳定的时钟信号作为支…...
软考教材重点内容 信息安全工程师 第22章 网站安全需求分析与安全保护工程
22.1.1 网站安全概念 网站是一个基于 B/S 技术架构的综合信息服务平台,主要提供网页信息及业务后台对外接口服务。一般网站涉及网络通信、操作系统、数据库、Web 服务器软件、Web 应用、浏览器、域名服务以及 HTML, XML,SSL; Web Services 等相关协议,同…...
数智读书笔记系列029 《代数大脑:揭秘智能背后的逻辑》
《代数大脑:揭秘智能背后的逻辑》书籍简介 作者简介 加里F. 马库斯(Gary F. Marcus)是纽约大学心理学荣休教授、人工智能企业家,曾创立Geometric Intelligence(后被Uber收购)和Robust.AI公司。他在神经科学、语言学和人工智能领域发表了大量论文,并著有《重启AI》等多部…...
UWB技术与5G、物联网结合的应用前景
一、核心应用场景与优势 工业自动化与智能制造 高精度设备协同:UWB技术(3cm定位精度)与5G(1ms级时延)结合,可实时追踪AGV、机械臂等设备位置,优化生产节拍,提升效率20…...
vue + element-plus自定义表单验证(修改密码业务)
写一个vue组件Password.vue 没有表单验证只有3个表单项 <template><div><el-form><el-form-item label"旧密码"><el-input></el-input></el-form-item><el-form-item label"新密码"><el-input>&l…...
如何将 Vue-FastAPI-Admin 项目的数据库从 SQLite 切换到 MySQL?
近期在github上看到一个开源项目,vue-fastapi-admin。它基于 FastAPI Vue3 Naive UI 的现代化前后端分离开发平台,融合了 RBAC 权限管理、动态路由和 JWT 鉴权,助力中小型应用快速搭建,也可用于学习参考。 由于该项目中数据库用…...
K8S运维实战之集群证书升级与容器运行时更换全记录
第一部分:Kubernetes集群证书升级实战 tips:此博文只演示一个节点作为示范,所有的集群节点步骤都可以参考。 项目背景 某金融业务系统Kubernetes集群即将面临生产证书集中过期风险(核心组件证书剩余有效期不足90天),…...
idea如何克隆拉取远程git项目到本地
概述 idea如何克隆拉取远程git项目到本地?方法很简单,找到入口,跟着引导窗口下一步下一步即可。 方法 File -> New -> Project from Version Control...然后根据引导窗口,一步一步操作即可...
聚铭网络亮相2025超云产品技术大会,联合发布“铭智安全运营大模型一体机及解决方案”
4月11日,于南京银城皇冠假日酒店举办的2025超云产品技术大会圆满落幕。聚铭网络受邀出席本次大会,并与超云联合发布了“铭智安全运营大模型一体机及解决方案”,为智能安全运营领域带来了全新突破。 会议背景 在全球人工智能技术加速产业化…...
成员访问运算符重载(详解)
目录 成员访问运算符 两层结构下的使用 三层结构下的使用(难点) 内存分析 成员访问运算符 成员访问运算符包括箭头访问运算符 -> 和解引用运算符 * ,它们是指针操作最常用的两个运算符。我们先来看箭头运算符 -> 箭头运算符只能以…...
无感改造,完美监控:Docker 多阶段构建 Go 应用无侵入观测
作者:牧思 背景 随着云原生的普及,Golang 编程语言变得越来越热门。相比 Java,Golang 凭借其轻量,易学习的特点得到了越来越多工程师的青睐,然而由于 Golang 应用需要被编译成二进制文件再进行运行,Golan…...
项目后期发现重大漏洞,如何紧急修复
项目后期发现重大漏洞的紧急修复关键在于: 迅速识别漏洞根本原因、制定修复优先级、协调团队资源、实施快速修复和验证、总结经验防止重复发生。 其中,迅速识别漏洞根本原因是最为关键的一步。找到漏洞的根本原因有助于确保修复措施不仅解决眼前的问题&a…...
设计模式:状态模式 - 复杂状态切换的优雅之道
一、为什么用状态模式? 在开发过程中,你是否遇到过这样的难题:对象需要根据不同的状态执行不同行为,但代码中却充斥着大量的if-else或switch-case语句? 随着状态的增多,代码变得臃肿且难以阅读࿰…...
【AI提示词】业务开发经理
提示说明 业务开发经理旨在帮助用户构建一个高效、有洞察力的业务发展角色,能够在竞争激烈的市场中寻找并抓住商机。 提示词 # 角色 业务开发经理专家## 注意 - 业务开发经理应具备强烈的市场洞察力和人际沟通能力。 - 专家设计应考虑业务发展的实际需求和挑战。…...
发电机参数详解
一、发电机参数体系概述 发电机作为将机械能转换为电能的核心设备,其参数体系涵盖电气、机械、结构、性能、控制五大维度,是设备选型、运行维护、故障诊断的重要依据。参数体系的完整性和准确性直接影响电力系统的稳定性与经济性。以下通过思维导图展示发电机参数的整体架构…...
每天五分钟深度学习PyTorch:RNN CELL模型原理以及搭建
本文重点 RNN Cell(循环神经网络单元)是循环神经网络(RNN)的核心组成部分,用于处理序列数据中的每个时间步,并维护隐藏状态以捕获序列中的时间依赖关系。 RNN CELL的结构 RNN是一个循环结构,它可以看作是RNN CELL的循环,RNN CELL的结构如下图所示,RNN CELL不断进行…...
设计和实现一个基于 DDS(直接数字频率合成) 的波形发生器
设计和实现一个基于 DDS(直接数字频率合成) 的波形发生器 1. 学习和理解IP软核和DDS 关于 IP 核的使用方法 IP 核:在 FPGA 设计中,IP 核(Intellectual Property Core)是由硬件描述语言(HDL&a…...
RCEP框架下eBay日本站选品战略重构:五维解析关税红利机遇
2024年RCEP深化实施背景下,亚太跨境电商生态迎来结构性变革。作为协定核心成员的日本市场,其跨境电商平台正经历新一轮价值重构。本文将聚焦eBay日本站,从政策解读到实操路径,系统拆解跨境卖家的战略机遇。 一、关税递减机制下的…...
使用 Node.js、Express 和 React 构建强大的 API
了解如何使用 Node.js、Express 和 React 创建一个强大且动态的 API。这个综合指南将引导你从设置开发环境开始,到集成 React 前端,并利用 APIPost 进行高效的 API 测试。无论你是初学者还是经验丰富的开发者,这篇文章都适合你。 今天&#…...
如何争取高层对项目的支持
争取高层对项目的支持关键在于明确项目的战略价值、展示其可行性与回报、以及有效的沟通和利益对接。高层管理者通常关注的是项目如何帮助公司实现整体战略目标,如何提高企业的竞争力或收益。在争取支持的过程中,项目经理需要清楚地表达项目的潜在价值&a…...
git合并分支原理
Git合并的原理是基于三方合并(three-way merge)算法,它通过比较三个快照来合并不同分支上的更改。这三个快照包括两个要合并的分支的最新提交和它们的共同祖先提交。合并过程并不是简单地按照提交时间来进行,而是通过比较这些快照…...
最短路问题
最短路问题 最短路问题 最短路算法(Shortest Path Algorithm)是用来解决图中两点之间的最短路径的问题。常见的应用包括:地图导航、网络路由、游戏寻路等。根据图的性质(有向/无向、是否有负权边)和需求(…...
ARM Cortex汇编伪指令
在ARM架构(尤其是Cortex-M系列MCU)的汇编中,伪指令(Pseudo-Instructions)是由汇编器解释的特殊指令,用于定义数据、符号、代码结构或控制汇编过程。以下是常用的ARM汇编伪指令分类及说明: 一、…...
如何在vue3项目中使用 AbortController取消axios请求
在 Vue3 项目中通过 AbortController 取消 Axios 请求,可以通过以下 结构化步骤 实现。我们结合组合式 API(Composition API)和现代前端实践演示: 一、基础实现(单个请求) 1. 创建组件逻辑 <script s…...
Bright+Data网页解锁器在旅游行业的创新实践
引言 随着在线旅游平台的快速发展,网络爬虫技术成为获取旅游数据的重要手段。然而,主流旅游网站(如去哪儿网、携程等)普遍部署了反爬虫机制,包括IP封禁、验证码验证、请求频率限制等技术手段,严重影响了传…...
SpringMVC 执行流程
前言: 在前后端分离的情况下,SpringMVC 的执行流程主要集中在处理 RESTful 请求和返回 JSON 数据。这里的 Controller 会直接返回数据,而不是视图。我们通常会使用 RestController 和 RequestMapping 来处理请求,ResponseBody 会…...