当前位置: 首页 > news >正文

Linux进程通信入门:匿名管道的原理、实现与应用场景

Linux系列


文章目录

  • Linux系列
  • 前言
  • 一、进程通信的目的
  • 二、进程通信的原理
    • 2.1 进程通信是什么
    • 2.2 匿名管道通讯的原理
  • 三、进程通讯的使用
  • 总结


前言

Linux进程间同通讯(IPC)是多个进程之间交换数据和协调行为的重要机制,是我们学习Linux操作系统中比较重要的一个模块。


一、进程通信的目的

Linux 进程间通信(IPC)的主要目的是让多个独立的进程能够协作、共享资源、交换数据或同步操作。这是现代操作系统中多任务、并行计算和分布式系统的核心基础。以下是具体的目的和场景:

  • 数据传输:一个进程需要将它的数据发送给另一个进程
  • 协同工作:两进程需要更具对方的执行结果来协同完成某种任务
  • 资源同步与互斥:避免多个进程同时访问共享资源导致数据竞争或状态不一致

二、进程通信的原理

2.1 进程通信是什么

进程通信的本质其实就是多个进程可以同时访问同一份“资源”。对于进程来说“资源”就是空间中存储的数据,所以要实现进程通信我们只需要让多个进程可以同时访问同一块空间即可。这里我们就以两个进程为例:
在这里插入图片描述
这时我们只需要做到让进程1向这块空间中写数据,进程2可以将进程1写入的数据从空间中取出,这样就完成了通讯工作。那么这块空间该由谁提供呢?由于进程必须保证独立性(也就是说不论这个空间由哪个进程提供,另一个进程都不能对它访问,否则就破坏了独立性),也就注定了这块共享空间只能由第三方提供---------操作系统,那么这块空间就必须由操作系统管理了,空间的创建到释放都是由操作系统来完成的,所以我们对这块空间的访问,就变成了对操作系统的访问,而进程(代表用户)要想访问操作系统,只能通过系统调用接口进行。
为了满足通讯需求,一般操作系统都会有一个独立的通信模块。今天我们就来介绍基于文件级别的通讯方式------管道

2.2 匿名管道通讯的原理

根据上面的分析,我们首先要让两个进程看到同一份资源:

在这里插入图片描述

我们利用父进程创建子进程时的特点,这样就可以让两个进程(父和子)看到同一分空间,而我们的管道就是文件,它是内核文件,并不会向磁盘刷新内容,父子进程对他进行访问时并不需要在目录中查询,而是直接通过文件描述符查找,所以管道文件不用定义名字,因此被称为匿名管道。
到了这里我们仅解决了,让两个进程看到同一份空间,但是管道文件不支持以读写方式打开,也就是说我们上面的介绍,两个进程(父子进程)只能向管道中读,或只能向管道中写,而进程通讯一般为一个进程写,一个进程读。

在这里插入图片描述
所以进程在打开管道文件时,都会分别以读、写两种方式打开,当我们让父进程读取数据,子进程写入数据的形式通讯时(这个用户自己控制),父进程就关闭对应的写方式,子进程关闭对应的读方式,此时子进程就可以向管道文件的缓冲区写入数据供父进程读取。到了这里,我们就建立了进程通信的信道。

通过上面的介绍我们可以知道匿名管道通信的特点为:

  • 只能进行单向通信
  • 通信进程间需要有血缘关系,常用于父子

三、进程通讯的使用

首先我们先来认识需要用到的系统调用:

在这里插入图片描述
这个系统调用需要传递一个存储两个元素的整形数组,该参数为输出型参数,第一个元素为以读形式打开的文件描述符,第二从元素为以写形式打开的文件描述符。下面我们先实现一个简单的通信:
示例1:

include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<string>
#include<cstring>
using namespace std;int main()
{int pipefd[2];int n=pipe(pipefd);if(n<0)return 1;pid_t id=fork();//创建子进程if(id==0)//子进程{string str="Hello father process\n";close(pipefd[0]);//子关闭读权限write(pipefd[1],str.c_str(),strlen(str.c_str()));//向管道中写入数据exit(0);}close(pipefd[1]);//父关闭写权限char tmp[100]={0};read(pipefd[0],tmp,100);//从管道中读取数据cout<<tmp;return 0;
}

程序执行结果:
在这里插入图片描述
这给代码主要帮助我们理解上面介绍的,关闭文件描述符以及pipe()参数的作用。接下来我们会通过下面的代码示例,对我们的管道通信的四种情况进行总结。

情况1:读写端正常,管道为空,读端就要阻塞

#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<cstdio>
#include<cstring>
using namespace std;#define N 2
#define NUM 1024void Write(int wfd)
{char buff[NUM];string str="Hello ,I am child,pid:";pid_t self=getpid();int num=0;while(true){sleep(2);buff[0]=0;snprintf(buff,sizeof(buff),"%s%d---%d",str.c_str(),self,num++);//将要写入数据格式化到buffwrite(wfd,buff,strlen(buff));//将buff中的数据写入管道}
}void Read(int rfd)
{char buff[NUM];while(true){buff[0]=0;int n=read(rfd,buff,sizeof(buff));//从管道中读取数据if(n>0){cout<<"father get message:"<<buff<<endl;}else if(n==0){cout<<"father read fail"<<endl;}else break;}
}
int main()
{int pipefd[N];int n=pipe(pipefd);if(n<0)return 1;//调用失败程序返回pid_t id=fork();//创建子进程if(id<0)return 1;if(id==0)//child{close(pipefd[0]);//关闭读端Write(pipefd[1]);close(pipefd[1]);//这一步有没有都无所谓exit(0);}//fatherclose(pipefd[1]);//关闭写端Read(pipefd[0]);close(pipefd[0]);return 0;
}

在这里插入图片描述
想要的效果不好展示,大家可以自己跑以下看看程序执行过程
上述代码,子进程在进程在向管道中写入数据时,每间隔两秒写入一次,而父进程会阻塞等待,当子进程写入完成后父进程才会读取并返回。我们可以看到程序并没有执行cout<<"father read fail"<<endl;这也证明了父进程会进行阻塞等待,等待子进程写入。
个人感觉这已经能说明问题了,不知道你能不能get到

情况二:读写端正常,管道被写满,写端就要阻塞
接下来我们对上面代码进行一点小改动:

void Write(int wfd)
{char buff[NUM];string str="Hello ,I am child,pid:";pid_t self=getpid();int num=0;while(true){buff[0]=0;snprintf(buff,sizeof(buff),"%s%d---%d",str.c_str(),self,num++);//将要写入数据格式化到buffwrite(wfd,buff,strlen(buff));//将buff中的数据写入管道cout<<"已经写入了:"<<num<<"条信息"<<endl;//记录写入次数}}
void Read(int rfd)
{char buff[NUM];while(true){buff[0]=0;sleep(10);int n=read(rfd,buff,sizeof(buff));//从管道中读取数据if(n>0){cout<<"father get message:"<<buff<<endl;}else if(n==0){cout<<"father read fail"<<endl;}else break;}
}

我们让父进程等待10秒再读取,子进程一直写入。
在这里插入图片描述
此时你会看到当子进程入定数量的数据后,就会停止写入进入阻塞状态,等待父进程的读取,父进程读取成功后,子进程才能继续写入,其原因就直管道被写满了。

情况三:读端正常,写端关闭,读端就会读到0,表明读到了文件(pipe)结尾,不会阻塞

void Write(int wfd)
{char buff[NUM];string str="Hello ,I am child,pid:";pid_t self=getpid();int num=0;int cnt=5;//写入五次while(cnt--){sleep(1);buff[0]=0;snprintf(buff,sizeof(buff),"%s%d---%d",str.c_str(),self,num++);//将要写入数据格式化到buffwrite(wfd,buff,strlen(buff));//将buff中的数据写入管道}cout<<"我是写端,我关闭了"<<endl;
}void Read(int rfd)
{char buff[NUM];while(true){buff[0]=0;sleep(1);int n=read(rfd,buff,sizeof(buff));//从管道中读取数据if(n>0){cout<<"father get message:"<<buff<<endl;}else if(n==0){cout<<"father read fail"<<endl;}else break;}
}

在这里插入图片描述
这个图效果就很好了,当写端关闭时,读端读取到文件末尾返回0执行cout<<"father get message:"<<buff<<endl;,子进程退出变为僵尸。

情况四:写端正常,读端关闭,操作系统通过信号杀掉正在写入的进程。

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib> //stdlib.h
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>#define N 2
#define NUM 1024using namespace std;// child
void Writer(int wfd)
{string s = "hello, I am child";pid_t self = getpid();int number = 0;char buffer[NUM];while (true){sleep(1);// 构建发送字符串buffer[0] = 0; // 字符串清空, 只是为了提醒阅读代码的人,我把这个数组当做字符串了snprintf(buffer, sizeof(buffer), "%s-%d-%d", s.c_str(), self, number++);// cout << buffer << endl;// 发送/写入给父进程, system callwrite(wfd, buffer, strlen(buffer)); // strlen(buffer) + 1???}
}// father
void Reader(int rfd)
{char buffer[NUM];int cnt = 0;while(true){buffer[0] = 0; // system callssize_t n = read(rfd, buffer, sizeof(buffer)); //sizeof != strlenif(n > 0){buffer[n] = 0; // 0 == '\0'cout << "father get a message[" << getpid() << "]# " << buffer << endl;}else if(n == 0) {printf("father read file done!\n");break;}else break;cnt++;if(cnt>5) break;// cout << "n: " << n << endl;}
}int main()
{int pipefd[N] = {0};int n = pipe(pipefd);if (n < 0)return 1;// child -> w, father->rpid_t id = fork();if (id < 0)return 2;if (id == 0){// childclose(pipefd[0]);// IPC codeWriter(pipefd[1]);close(pipefd[1]);exit(0);}// fatherclose(pipefd[1]);// IPC codeReader(pipefd[0]); // 读取5sclose(pipefd[0]);cout << "father close read fd: " << pipefd[0] << endl;sleep(5); //为了观察僵尸int status = 0;pid_t rid = waitpid(id, &status, 0);    if(rid < 0) return 3;cout << "wait child success: " << rid << " exit code: " << ((status>>8)&0xFF) << " exit signal: " << (status&0x7F) << endl;sleep(5);cout << "father quit" << endl;return 0;
}

在这里插入图片描述
在这里插入图片描述
可以看到当读端关闭后,操作系统就会将使用13号信号杀掉写端。

总结

1、具有血缘关系的进程才能使用匿名管道通讯
2、管道只能单向通信
3、父子进程是会进程协同的,同步与互斥的------保护管道文件的数据安全
4、管道是门面向字节流的
5、管道是基于文件的,而文件的生命周期是随进程的

相关文章:

Linux进程通信入门:匿名管道的原理、实现与应用场景

Linux系列 文章目录 Linux系列前言一、进程通信的目的二、进程通信的原理2.1 进程通信是什么2.2 匿名管道通讯的原理 三、进程通讯的使用总结 前言 Linux进程间同通讯&#xff08;IPC&#xff09;是多个进程之间交换数据和协调行为的重要机制&#xff0c;是我们学习Linux操作系…...

[SpringMVC]上手案例

创建工程 新建项目&#xff0c;选择maven工程&#xff0c;原型&#xff08;Archetype&#xff09;选择maven的webapp&#xff0c;注意名称头尾。会使用到tomcat&#xff08;因为是javaWeb&#xff09;。 新建的项目结构目录如下&#xff0c;如果没有java目录&#xff0c;需要自…...

kubernetes 入门篇之架构介绍

经过前段时间的学习和实践&#xff0c;对k8s的架构有了一个大致的理解。 1. k8s 分层架构 架构层级核心组件控制平面层etcd、API Server、Scheduler、Controller Manager工作节点层Kubelet、Kube-proxy、CRI&#xff08;容器运行时接口&#xff09;、CNI&#xff08;网络插件&…...

说一说 Spring 中的事务

什么是事务&#xff1f; 事务就是用户定义的一系列执行SQL语句的操作, 这些操作要么完全地执行&#xff0c;要么完全地都不执行&#xff0c; 它是一个不可分割的工作执行单元。 Spring 中的事务是怎么实现的&#xff1f; Spring事务底层是基于数据库事务和AOP机制的首先对于…...

docker容器安装的可道云挂接宿主机的硬盘目录:解决群晖 威联通 飞牛云等nas的硬盘挂接问题

基于Docker部署可道云&#xff08;KodCloud&#xff09;时&#xff0c;通过挂载宿主机其他磁盘目录可实现高效、安全的数据管理。具体而言&#xff0c;使用绑定挂载&#xff08;Bind Mounts&#xff09;将宿主机目录&#xff08;如/data/disk2&#xff09;映射到容器内的可道云…...

Oracle 23ai Vector Search 系列之5 向量索引(Vector Indexes)

文章目录 Oracle 23ai Vector Search 系列之5 向量索引Oracle 23ai支持的向量索引类型内存中的邻居图向量索引 (In-Memory Neighbor Graph Vector Index)磁盘上的邻居分区矢量索引 (Neighbor Partition Vector Index) 创建向量索引HNSW索引IVF索引 向量索引示例参考 Windows 环…...

GPT模型架构与文本生成技术深度解析

核心发现概述 本文通过系统分析OpenAI的GPT系列模型架构&#xff0c;揭示其基于Transformer解码器的核心设计原理与文本生成机制。研究显示&#xff0c;GPT模型通过自回归机制实现上下文感知的序列生成&#xff0c;其堆叠式解码器结构配合创新的位置编码方案&#xff0c;可有效…...

【读者求助】如何跨行业进入招聘岗位?

文章目录 读者留言回信岗位细分1. 中介公司的招聘岗位2. 猎头专员3. 公司的招聘专员选择建议 面试建议1. 请简单介绍你过去 3 年的招聘工作经历&#xff0c;重点说下你负责的岗位类型和规模2. 你在招聘流程中最常用的渠道有哪些&#xff1f;如何评估渠道效果&#xff1f;3. 当你…...

2025蓝桥杯省赛C++B组解题思路

由于题面还没出来&#xff0c;现在先口胡一下思路 填空题直接打表找规律或者乱搞一下就能出&#xff0c;从大题开始说。 1&#xff0c;题意&#xff1a; 给你一个数组&#xff0c;这个数组里有几个数可以被一个连续递增的数字区间求和得出 思路&#xff1a;诈骗题&#xff0c;显…...

springcloud整理

问题1.服务拆分后如何进行服务之间的调用 我们该如何跨服务调用&#xff0c;准确的说&#xff0c;如何在cart-service中获取item-service服务中的提供的商品数据呢&#xff1f; 解决办法&#xff1a;Spring给我们提供了一个RestTemplate的API&#xff0c;可以方便的实现Http请…...

游戏引擎学习第220天

介绍 今天的工作主要是进行一些代码整理和清理&#xff0c;目的是将我们之前写过的代码重新整合在一起&#xff0c;使它们能够更好地协同工作。现在的阶段&#xff0c;我们的任务并不是进行大规模的功能开发&#xff0c;而是集中精力对现有的代码进行整合和思考&#xff0c;确…...

OceanBase企业版单机部署:obd命令行方式

OceanBase企业版单机部署&#xff1a;obd命令行方式 安装包准备服务器准备最低资源配置是否部署ODP组件&#xff1f;仲裁服务器 服务器配置操作系统内核参数BIOS设置磁盘挂载网卡设置 obd部署前配置obd部署单机版安装obd配置obd部署OB集群部署后检查 环境清理与集群销毁 本文介…...

KWDB创作者计划—KWDB认知引擎:数据流动架构与时空感知计算的范式突破

引言&#xff1a;数据智能的第三范式 在数字化转型进入深水区的2025年&#xff0c;企业数据系统正面临三重悖论&#xff1a;数据规模指数级增长与实时决策需求之间的矛盾、多模态数据孤岛与业务连续性要求之间的冲突、静态存储范式与动态场景适配之间的鸿沟。KWDB&#xff08;K…...

车载通信系统中基于ISO26262的功能安全与抗辐照协同设计研究

摘要&#xff1a;随着智能网联汽车的快速发展&#xff0c;车载通信系统正面临着功能安全与抗辐照设计的双重挑战。在高可靠性要求的车载应用场景下&#xff0c;如何实现功能安全标准与抗辐照技术的协同优化&#xff0c;构建满足ISO26262安全完整性等级要求的可靠通信架构&#…...

Oracle OCP认证考试考点详解083系列03

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 11. 第11题&#xff1a; 题目 解析及答案&#xff1a; 关于 RMAN&#xff08;恢复管理器&#xff09;多路复用备份集&#xff0c;以下哪…...

Spring

一.Ioc&DI 1.类的五种控制反转注解 这五个注解作用都一样&#xff0c;只是意义不一样&#xff0c;用来提高代码的可读性。 Controller&#xff1a;控制层&#xff0c;接收请求&#xff0c;对请求进⾏处理&#xff0c;并进⾏响应。 Servie&#xff1a;业务逻辑层&#xff0…...

基于开源链动2+1模式、AI智能名片与S2B2C商城小程序源码的体验式关系深化与商业转化研究

摘要&#xff1a;本文探讨了通过体验过程中的共同经历强化关系&#xff0c;促使KOC&#xff08;关键意见消费者&#xff09;为品牌背书的机制&#xff0c;并深入分析了开源链动21模式、AI智能名片以及S2B2C商城小程序源码在其中的创新应用。研究发现&#xff0c;这些新模式和技…...

【区块链安全 | 第三十九篇】合约审计之delegatecall(一)

文章目录 外部调用函数calldelegatecall call 与 delegatecall 的区别示例部署后初始状态调用B.testCall()函数调用B.testDelegatecall()函数区别总结 漏洞代码代码审计攻击代码攻击原理解析攻击流程修复建议审计思路 外部调用函数 在 Solidity 中&#xff0c;常见的两种底层外…...

Kingbase 常用运维命令总结

一、数据库连接与基础操作 连接指定服务器数据库 ksql -h 主机IP -p 端口号 -U 用户名 -d 数据库名 -W # 示例&#xff1a;连接 IP 为 192.168.1.100 的数据库 ksql -h 192.168.1.100 -p 54321 -U system -d test -W 断开数据库连接 \q 或 exit 查看数据库列表及详细信息…...

从零开始的C++编程 2(类和对象下)

目录 1.构造函数初始化列表 2.类型转换 3.static成员 4.友元 5.内部类 6.匿名对象 1.构造函数初始化列表 ①之前我们实现构造函数时&#xff0c;初始化成员变量主要使⽤函数体内赋值&#xff0c;构造函数初始化还有⼀种⽅式&#xff0c;就是初始化列表&#xff0c;初始化…...

Java---抽象类与接口

抽象类与接口 前言一、抽象类1.抽象类的概念2.抽象类的语法3.抽象类的特点4.抽象类的操作5.抽象类的作用 二、接口1.接口的概念2.接口语法3.接口的使用与特性4.实现多个接口5.接口之间的继承6.接口的实例(1).对象大小的比较(1).Comparable接口(2).Comparator接口 (2).实现类的克…...

玩转Docker | 使用Docker部署linkding书签管理工具

玩转Docker | 使用Docker部署linkding书签管理工具 前言一、linkding介绍简介主要特点二、系统要求环境要求环境检查Docker版本检查检查操作系统版本三、部署linkding服务下载镜像创建容器检查容器状态检查服务端口设置登录账号与密码安全设置四、访问linkding服务访问linkding…...

K8s 集群网络疑难杂症:解决 CNI 网络接口宕机告警的完整指南

引言 在 Kubernetes 集群运维过程中,网络问题往往是最棘手的故障之一。当你收到一条 [CRITICAL] 网络接口宕机 (172.18.109.55:9100) 的告警,并且告警内容显示 172.18.109.55:9100 的网络接口 cni0 已宕机5分钟 时,这通常意味着你的 Kubernetes 集群中有一个节点的容器网络…...

程序员/运维绘图工具---Mermaid

效果 介绍 Mermaid 是一种基于文本的图表生成工具&#xff0c;通过类似 Markdown 的简洁语法快速创建流程图、甘特图、类图等各类专业图表 应用场景 程序员绘图 系统架构图&代码逻辑可视化 项目管理图 数据可视化 AI辅助生成&#xff1a;LLM生成mermaid代码然后去渲染成…...

《MATLAB实战训练营:从入门到工业级应用》趣味入门篇-用MATLAB画一朵会动的3D玫瑰:从零开始的浪漫编程之旅

《MATLAB实战训练营&#xff1a;从入门到工业级应用》趣味入门篇-&#x1f339;用MATLAB画一朵会动的3D玫瑰&#xff1a;从零开始的浪漫编程之旅 你是否想过用代码创造一朵永不凋谢的玫瑰&#xff1f;今天&#xff0c;我将带你走进MATLAB的奇妙世界&#xff0c;用数学公式和编…...

激光院董事长龚赤坤到北京研发中心检查指导工作

4月11日&#xff0c;激光院党委书记、董事长龚赤坤到北京研发中心检查指导工作。 龚赤坤详细了解了北京研发中心的建设情况和科研进展&#xff0c;充分肯定所取得的成绩&#xff0c;对发展寄予厚望&#xff0c;龚赤坤指出北京研发中心的成立正处于激光院加速发展与产业进化的关…...

AbortController:让异步操作随时说停就停

AbortController&#xff1a;让异步操作随时说停就停 一、什么是 AbortController&#xff1f; AbortController 是 JavaScript 在浏览器和部分 Node.js 环境中提供的全局类&#xff0c;用来中止正在进行或待完成的异步操作&#xff08;如 fetch() 请求、事件监听、可写流、数…...

leetcode572 另一棵树的子树

1.与100、101解法相同 递归&#xff1a; class Solution { private:bool compare(TreeNode* p, TreeNode* q){if(!p && !q) return true;else if(!p || !q) return false;else if(p->val ! q->val) return false;bool leftside compare(p->left, q->lef…...

再看 MPTCP 时的思考

2022 年夏&#xff0c;居家办公时&#xff0c;第一次接手 mptcp 就觉得它不靠谱&#xff0c;以至于我后来搞了 mpudp for DC&#xff0c;再后来我调研了很多 mptcp-based 方案&#xff0c;发现它们都是向善而来&#xff0c;最终灰头土脸而终。mptcp 实则一个坑&#xff0c;业内…...

将三维非平面点集拆分为平面面片的MATLAB实现

将三维非平面点集拆分为平面面片的MATLAB实现 要将三维空间中不在同一平面上的点集拆分为多个平面面片&#xff0c;可以采用以下几种方法&#xff1a; 1. 三角剖分法 (Delaunay Triangulation) 最简单的方法是将点集进行三角剖分&#xff0c;因为三个点总是共面的&#xff1…...

Python(10.2)Python可变与不可变类型内存机制解密:从底层原理到工程实践

目录 一、类型特性引发的内存现象1.1 电商促销活动事故分析1.2 内存机制核心差异 二、内存地址追踪实验2.1 基础类型验证2.2 复合对象实验 三、深度拷贝内存分析3.1 浅拷贝陷阱3.2 深拷贝实现 四、函数参数传递机制4.1 默认参数陷阱4.2 安全参数模式 五、内存优化最佳实践5.1 字…...

华为hcie证书的有效期怎么判断?

在ICT行业&#xff0c;华为HCIE证书堪称含金量极高的“敲门砖”&#xff0c;拥有它往往意味着在职场上更上一层楼。然而&#xff0c;很多人在辛苦考取HCIE证书后&#xff0c;却对其有效期相关事宜一知半解。今天&#xff0c;咱们就来好好唠唠华为HCIE证书的有效期怎么判断这个关…...

【前端】CSS Grid 布局详解

CSS Grid 布局详解&#xff08;通俗易懂版&#xff09; 一、概述 CSS Grid 是一种二维布局系统&#xff0c;可以同时控制行和列&#xff0c;相比 Flex&#xff08;一维布局&#xff09;&#xff0c;更适合用在整体页面布局或复杂模块结构中。 二、基础概念 Grid 容器&#x…...

物美“外贸转内销”极速绿色通道正式开启

「TMT星球」获悉&#xff0c;在国家“提振消费、扩大内需”及“内外贸一体化”战略指引下&#xff0c;物美集团依托自身零售生态优势&#xff0c;打造“云超绿通”专项通道&#xff0c;助力中国优质外贸企业实现“出口转内销”的高效转型&#xff0c;通过极速绿通、线上线下全渠…...

【说明书#1】Node.js 和 npm安装与使用

系统提示 npm 不是内部或外部命令,也不是可运行的程序或批处理文件,也就是 npm 命令无法识别。这个错误通常是因为 Node.js 和 npm 没有正确安装,或者它们的路径没有添加到系统的环境变量中。 解决方法如下: 1. 安装 Node.js 和 npm: 如果你还没有安装 Node.js,可以从…...

【触想智能】安卓工业平板电脑和普通商业平板电脑的区别

安卓工业平板电脑是基于ARM架构开发的一种工业平板电脑&#xff0c;它在自助终端、智能制造、产线车间、智慧物流、商业金融等诸多领域有着广泛的应用。 触想安卓工业平板电脑TPC-A2系列 安卓工业平板电脑和普通商业平板电脑在一些方面存在一些区别&#xff0c;包括设计、硬件规…...

Java基于SSM的课程答疑微信小程序【附源码、文档说明】

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…...

模板引擎语法-变量

模板引擎语法-变量 文章目录 模板引擎语法-变量&#xff08;一&#xff09;在Django框架模板中使用变量的代码实例&#xff08;二&#xff09;在Django框架模板中使用变量对象属性的代码实例&#xff08;三&#xff09;在Django框架模板中使用变量显示列表 &#xff08;一&…...

1260 最大公约数

1260 最大公约数 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;GCD &#x1f4d6; &#x1f4da; import java.util.Scanner; import java.util.Arrays;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int t …...

Node.js中net模块详解

Node.js 中 net 模块 API 详解 Node.js 的 net 模块提供了基于 TCP/IP 的网络功能&#xff0c;用于创建 TCP 服务器和客户端。以下是 net 模块的所有 API 详解&#xff1a; 1. 创建 TCP 服务器 const net require(net);// 1. 基本服务器 const server net.createServer((s…...

【从零开始学习JVM | 第三篇】虚拟机的垃圾回收学习(一)

堆空间的基本结构 Java 的自动内存管理主要是针对对象内存的回收和对象内存的分配。同时&#xff0c;Java 自动内存管理最核心的功能是 堆 内存中对象的分配与回收。 Java 堆是垃圾收集器管理的主要区域&#xff0c;因此也被称作 GC 堆&#xff08;Garbage Collected Heap&am…...

intellj idea 2024.1

参考资料 激活 https://www.microcharon.com/tech/5.htmlja-netfilter-all下载地址&#xff1a;https://drive.microcharon.com/OneDrive/Software/JetBrains%20ja-netfilter-all%20Build%202024.1.11.zip 步骤及问题 下载后&#xff1a;安全前确保旧版本的idea已经卸载。安…...

redis之缓存击穿

一、前言 本期我们聊一下缓存击穿&#xff0c;其实缓存击穿和缓存穿透很相似&#xff0c;区别就是&#xff0c;缓存穿透是一些黑客故意请求压根不存在的数据从而达到拖垮系统的目的&#xff0c;是恶意的&#xff0c;有针对性的。缓存击穿的情况是&#xff0c;数据确实存在&…...

Node.js中path模块详解

Node.js path 模块全部 API 详解 Node.js 的 path 模块提供了处理文件路径的工具函数&#xff0c;支持跨平台路径操作。以下是 path 模块的所有 API 详解&#xff1a; 1. 路径解析与操作 const path require(path);// 1. 路径连接 const fullPath path.join(__dirname, fi…...

重构艺术 | 内联与查询替代临时变量

重构艺术 | 内联与查询替代临时变量 在代码重构的殿堂里&#xff0c;临时变量常常扮演着双面角色&#xff1a;既是代码清晰的助力器&#xff0c;也可能成为代码腐败的温床。本文将深入探讨两种处理临时变量的重要手法&#xff1a;内联临时变量&#xff08;Inline Temp&#xf…...

数据分析-数据预处理

数据分析-数据预处理 处理重复值 duplicated( )查找重复值 import pandas as pd apd.DataFrame(data[[A,19],[B,19],[C,20],[A,19],[C,20]],columns[name,age]) print(a) print(--------------------------) aa.duplicated() print(a)只判断全局不判断每个 any() import p…...

Java基础 4.12

1.方法的重载&#xff08;OverLoad&#xff09; 基本介绍 Java中允许同一个类&#xff0c;多个同名方法的存在&#xff0c;但要求形参列表不一致&#xff01; 如 System.out.println(); out是PrintStream类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 2.重载的快速入…...

PostgreSQL有类似oracle的move表吗

PostgreSQL有类似oracle的move表吗 PostgreSQL 提供了类似 Oracle MOVE 表功能的重组操作&#xff0c;但实现方式和具体命令有所不同。以下是详细对比和 PostgreSQL 中的实现方案&#xff1a; 一 Oracle MOVE 与 PostgreSQL 对比 特性Oracle MOVEPostgreSQL 等效操作主要用途…...

AUTO-RAG: AUTONOMOUS RETRIEVAL-AUGMENTED GENERATION FOR LARGE LANGUAGE MODELS

Auto-RAG&#xff1a;用于大型语言模型的自主检索增强生成 单位&#xff1a;中科院计算所 代码&#xff1a; https://github.com/ictnlp/Auto-RAG 拟解决问题&#xff1a;通过手动构建规则或者few-shot prompting产生的额外推理开销。 贡献&#xff1a;提出一种以LLM决策为中…...

ABC-CNN-GRU-Attention、CNN-GRU-Attention、ABC-CNN-GRU和CNN-GRU四类对比模型多变量时序预测

人工蜂群算法四模型对比&#xff01;ABC-CNN-GRU-Attention系列四模型多变量时序预测 目录 人工蜂群算法四模型对比&#xff01;ABC-CNN-GRU-Attention系列四模型多变量时序预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 本研究针对多变量时间序列预测任务&#xf…...