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

Linux进程间通信(上)(21)

文章目录

  • 前言
  • 一、什么是进程间通信?
    • 概念
    • 目的
    • 本质
    • 分类
  • 二、管道
    • 什么是管道
    • 匿名管道
      • 匿名管道的原理
      • pipe函数
      • 匿名管道使用步骤
      • 管道读写规则
      • 管道的特点
      • 管道的四种特殊情况
      • 管道的大小
  • 总结


前言

  本篇出得有点慢,因为我在这里更换了我的开发环境
  不再使用Vim,而是替换成Vscode这个更加强大的文本编辑器!!!
  且不再使用Centos,官方早已宣布不再维护它,所以我更换了操作系统Ubuntu


一、什么是进程间通信?

概念

  进程间通信简称IPC(Interprocess communication),进程间通信就是在不同进程之间传播或交换信息

进程具有独立性,所以怎么交换信息,这就成了一个问题

目的

  • 数据传输: 一个进程需要将它的数据发送给另一个进程。
  • 资源共享: 多个进程之间共享同样的资源。
  • 通知事件: 一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件,比如进程终止时需要通知其父进程。
  • 进程控制: 有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

本质

进程间通信的本质就是,让不同的进程看到同一份资源。

  由于各个运行进程之间具有独立性,这个独立性主要体现在数据层面,而代码逻辑层面可以私有也可以公有(例如父子进程),因此各个进程之间要实现通信是非常困难的。

  各个进程之间若想实现通信,一定要借助第三方资源,这些进程就可以通过向这个第三方资源写入或是读取数据,进而实现进程之间的通信,这个第三方资源实际上就是操作系统提供的一段内存区域

在这里插入图片描述
  因此,进程间通信的本质就是,让不同的进程看到同一份资源(内存,文件内核缓冲等)。 由于这份资源可以由操作系统中的不同模块提供,因此出现了不同的进程间通信方式。

分类

管道

  • 匿名管道
  • 命名管道

System V IPC

  • System V 消息队列
  • System V 共享内存
  • System V 信号量

POSIX IPC

  • 消息队列
  • 共享内存
  • 信号量
  • 互斥量
  • 条件变量
  • 读写锁

二、管道

可以说进程间通信的方法有很多,我们暂且先从管道开始讲起

什么是管道

  管道是Unix中最古老的进程间通信的形式,我们把从一个进程连接到另一个进程的数据流称为一个“管道”

  例如,统计我们当前使用云服务器上的登录用户个数。

在这里插入图片描述
  其中,who命令和wc命令都是两个程序,当它们运行起来后就变成了两个进程,who进程通过标准输出将数据打到“管道”当中,wc进程再通过标准输入从“管道”当中读取数据,至此便完成了数据的传输,进而完成数据的进一步加工处理。

在这里插入图片描述

  注明: who命令用于查看当前云服务器的登录用户(一行显示一个用户),wc -l 用于统计当前的行数。

匿名管道

匿名管道的原理

匿名管道用于进程间通信,且仅限于本地父子进程之间的通信。

  进程间通信的本质就是,让不同的进程看到同一份资源,使用匿名管道实现父子进程间通信的原理就是,让两个父子进程先看到同一份被打开的文件资源,然后父子进程就可以对该文件进行写入或是读取操作,进而实现父子进程间通信。

在这里插入图片描述
注意:

  • 这里父子进程看到的同一份文件资源是由操作系统来维护的,所以当父子进程对该文件进行写入操作时,该文件缓冲区当中的数据并不会进行写时拷贝。

  • 管道虽然用的是文件的方案,但操作系统一定不会把进程进行通信的数据刷新到磁盘当中,因为这样做有IO参与会降低效率,而且也没有必要。也就是说,这种文件是一批不会把数据写到磁盘当中的文件,换句话说,磁盘文件和内存文件不一定是一一对应的,有些文件只会在内存当中存在,而不会在磁盘当中存在。

pipe函数

  pipe函数用于创建匿名管道,pipe函数的函数原型如下

int pipe(int pipefd[2]);

  pipe函数的参数是一个输出型参数,数组pipefd用于返回两个指向管道读端和写端的文件描述符

数组元素含义
pipefd[0]管道读端的文件描述符
pipefd[1]管道写端的文件描述符

  pipe函数调用成功时返回0,调用失败时返回-1。

匿名管道使用步骤

  在创建匿名管道实现父子进程间通信的过程中,需要 pipe函数 和 fork函数 搭配使用

具体步骤如下:

  1. 父进程调用pipe函数创建管道。

在这里插入图片描述

  1. 父进程创建子进程。

在这里插入图片描述

  1. 父进程关闭写端,子进程关闭读端。

在这里插入图片描述
注意:

  1. 管道只能够进行单向通信,因此当父进程创建完子进程后,需要确认父子进程谁读谁写,然后关闭相应的读写端。
  2. 从管道写端写入的数据会被内核缓冲,直到从管道的读端被读取。

我们现在可以站在文件描述符的角度再来看看这三个步骤:

  1. 父进程调用pipe函数创建管道

在这里插入图片描述

  1. 父进程创建子进程。

在这里插入图片描述

  1. 父进程关闭写端,子进程关闭读端。
    在这里插入图片描述

  在以下代码当中,子进程向匿名管道当中写入10行数据,父进程从匿名管道当中将数据读出

//child->write, father->read                                                                                                                                                                                                                                                                                                                                                                                                                                                        
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{int fd[2] = { 0 };if (pipe(fd) < 0){ //使用pipe创建匿名管道perror("pipe");return 1;								}pid_t id = fork(); //使用fork创建子进程if (id == 0){//childclose(fd[0]);  //子进程关闭读端//子进程向管道写入数据const char* msg = "hello father, I am child...";int count = 10;while (count--){write(fd[1], msg, strlen(msg));sleep(1);}close(fd[1]); //子进程写入完毕,关闭文件exit(0);}//fatherclose(fd[1]); //父进程关闭写端//父进程从管道读取数据char buff[64];while (1){ssize_t s = read(fd[0], buff, sizeof(buff));if (s > 0){buff[s] = '\0';printf("child send to father:%s\n", buff);}else if (s == 0){printf("read file end\n");break;}else{printf("read error\n");break;}}close(fd[0]); //父进程读取完毕,关闭文件waitpid(id, NULL, 0);return 0;
}

在这里插入图片描述

管道读写规则

  pipe2函数与pipe函数类似,也是用于创建匿名管道,其函数原型如下:

int pipe2(int pipefd[2], int flags);

  pipe2函数的第二个参数用于设置选项。

1、当没有数据可读时:

  • O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来为止。
  • O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。

2、当管道满的时候:

  • O_NONBLOCK disable:write调用阻塞,直到有进程读走数据。
  • O_NONBLOCK enable:write调用返回-1,errno值为EAGAIN。

3、如果所有管道写端对应的文件描述符被关闭,则read返回0。
4、如果所有管道读端对应的文件描述符被关闭,则 write操作 会产生 信号SIGPIPE ,进而可能导致 write进程 退出。
5、当要写入的数据量不大于PIPE_BUF时,Linux将保证写入的原子性。
6、当要写入的数据量大于PIPE_BUF时,Linux将不再保证写入的原子性。

管道的特点

  1. 管道内部自带同步与互斥机制。

  我们将一次只允许一个进程使用的资源,称为临界资源。管道在同一时刻只允许一个进程对其进行写入或是读取操作,因此管道也就是一种临界资源。

  临界资源是需要被保护的,若是我们不对管道这种临界资源进行任何保护机制,那么就可能出现同一时刻有多个进程对同一管道进行操作的情况,进而导致同时读写、交叉读写以及读取到的数据不一致等问题。

  为了避免这些问题,内核会对管道操作进行同步与互斥:

  同步: 两个或两个以上的进程在运行过程中协同步调,按预定的先后次序运行。比如,A任务的运行依赖于B任务产生的数据。
  互斥: 一个公共资源同一时刻只能被一个进程使用,多个进程不能同时使用公共资源。

  实际上,同步是一种更为复杂的互斥,而互斥是一种特殊的同步。对于管道的场景来说,互斥就是两个进程不可以同时对管道进行操作,它们会相互排斥,必须等一个进程操作完毕,另一个才能操作,而同步也是指这两个不能同时对管道进行操作,但这两个进程必须要按照某种次序来对管道进行操作。

  也就是说,互斥具有唯一性和排它性,但互斥并不限制任务的运行顺序,而同步的任务之间则有明确的顺序关系。

  1. 管道的生命周期随进程。

  管道本质上是通过文件进行通信的,也就是说管道依赖于文件系统,那么当所有打开该文件的进程都退出后,该文件也就会被释放掉,所以说管道的生命周期随进程。

  1. 管道提供的是流式服务。

  对于进程A写入管道当中的数据,进程B每次从管道读取的数据的多少是任意的,这种被称为流式服务,与之相对应的是数据报服务

流式服务: 数据没有明确的分割,不分一定的报文段。
数据报服务: 数据有明确的分割,拿数据按报文段拿。

  1. 管道是半双工通信的。

在数据通信中,数据在线路上的传送方式可以分为以下三种:

  1. 单工通信(Simplex Communication):单工模式的数据传输是单向的。通信双方中,一方固定为发送端,另一方固定为接收端。
  2. 半双工通信(Half Duplex):半双工数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。
  3. 全双工通信(Full Duplex):全双工通信允许数据在两个方向上同时传输,它的能力相当于两个单工通信方式的结合。全双工可以同时(瞬时)进行信号的双向传输。

管道是半双工的,数据只能向一个方向流动,需要双方通信时,需要建立起两个管道。

在这里插入图片描述

管道的四种特殊情况

在使用管道时,可能出现以下四种特殊情况

  1. 写端进程不写,读端进程一直读,那么此时会因为管道里面没有数据可读,对应的读端进程会被挂起,直到管道里面有数据后,读端进程才会被唤醒。
  2. 读端进程不读,写端进程一直写,那么当管道被写满后,对应的写端进程会被挂起,直到管道当中的数据被读端进程读取后,写端进程才会被唤醒。
  3. 写端进程将数据写完后将写端关闭,那么读端进程将管道当中的数据读完后,就会继续执行该进程之后的代码逻辑,而不会被挂起。
  4. 读端进程将读端关闭,而写端进程还在一直向管道写入数据,那么操作系统会将写端进程杀掉。

  其中前面两种情况就能够很好的说明,管道是自带同步与互斥机制的,读端进程和写端进程是有一个步调协调的过程的,不会说当管道没有数据了读端还在读取,而当管道已经满了写端还在写入。读端进程读取数据的条件是管道里面有数据,写端进程写入数据的条件是管道当中还有空间,若是条件不满足,则相应的进程就会被挂起,直到条件满足后才会被再次唤醒。

  第三种情况也很好理解,读端进程已经将管道当中的所有数据都读取出来了,而且此后也不会有写端再进行写入了,那么此时读端进程也就可以执行该进程的其他逻辑了,而不会被挂起。

  第四种情况也不难理解,既然管道当中的数据已经没有进程会读取了,那么写端进程的写入将没有意义,因此操作系统直接将写端进程杀掉。而此时子进程代码都还没跑完就被终止了,属于异常退出,那么子进程必然收到了某种信号。

  我们可以通过以下代码看看情况四中,子进程退出时究竟是收到了什么信号

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>int main()
{int fd[2] = { 0 };if (pipe(fd) < 0){ //使用pipe创建匿名管道perror("pipe");return 1;}//使用fork创建子进程pid_t id = fork(); if (id == 0){//childclose(fd[0]); //子进程关闭读端//子进程向管道写入数据const char* msg = "hello father, I am child...";int count = 10;while (count--){write(fd[1], msg, strlen(msg));sleep(1);}close(fd[1]); //子进程写入完毕,关闭文件exit(0);}//fatherclose(fd[1]); //父进程关闭写端close(fd[0]); //父进程直接关闭读端(导致子进程被操作系统杀掉)int status = 0;waitpid(id, &status, 0);printf("child get signal:%d\n", status & 0x7F); //打印子进程收到的信号return 0;
}

  运行结果显示,子进程退出时收到的是13号信号。

在这里插入图片描述
  通过kill -l命令可以查看13对应的具体信号。

在这里插入图片描述
  由此可知,当发生情况四时,操作系统向子进程发送的是SIGPIPE信号将子进程终止的。

管道的大小

  管道的容量是有限的,如果管道已满,那么写端将阻塞或失败,那么管道的最大容量是多少呢?

方法一:使用man手册

  根据man手册,在2.6.11之前的Linux版本中,管道的最大容量与系统页面大小相同,从Linux 2.6.11往后,管道的最大容量是65536字节。

在这里插入图片描述

  然后我们可以使用 uname -r 命令,查看自己使用的Linux版本
在这里插入图片描述

方法二:使用ulimit命令

  其次,我们还可以使用 ulimit -a 命令,查看当前资源限制的设定。

在这里插入图片描述
  根据显示,管道的最大容量是 512 × 8 = 4096 字节。

方法三:自行测试

  这里发现,根据man手册得到的管道容量与使用ulimit命令得到的管道容量不同,那么此时我们可以自行进行测试。

  前面说到,若是读端进程一直不读取管道当中的数据,写端进程一直向管道写入数据,当管道被写满后,写端进程就会被挂起。据此,我们可以写出以下代码来测试管道的最大容量。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>int main()
{int fd[2] = { 0 };if (pipe(fd) < 0){ //使用pipe创建匿名管道perror("pipe");return 1;}pid_t id = fork();//使用fork创建子进程if (id == 0){//child close(fd[0]); //子进程关闭读端char c = 'a';int count = 0;//子进程一直进行写入,一次写入一个字节while (1){write(fd[1], &c, 1);count++;printf("%d\n", count); //打印当前写入的字节数}close(fd[1]);exit(0);}//fatherclose(fd[1]); //父进程关闭写端//父进程不进行读取waitpid(id, NULL, 0);close(fd[0]);return 0;
}

  可以看到,在读端进程不进行读取的情况下,写端进程最多写65536字节的数据就被操作系统挂起了,也就是说,我当前Linux版本中管道的最大容量是65536字节。

在这里插入图片描述


总结

  哎,计划赶不上变化~

相关文章:

Linux进程间通信(上)(21)

文章目录 前言一、什么是进程间通信&#xff1f;概念目的本质分类 二、管道什么是管道匿名管道匿名管道的原理pipe函数匿名管道使用步骤管道读写规则管道的特点管道的四种特殊情况管道的大小 总结 前言 本篇出得有点慢&#xff0c;因为我在这里更换了我的开发环境   不再使用…...

力扣面试150题--对称二叉树

Day 41 题目描述 做法 原理&#xff1a;拆分为根节点的左右两棵子树&#xff0c;比较左子树的右和右子树的左&#xff0c;左子树的左和右子树的右 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode righ…...

深度学习系统学习系列【6】之深度学习技巧

文章目录 数据集准备数据集扩展数据预处理1. 0均值&#xff08;Zero Centralization&#xff09;代码实现 2. 归一化&#xff08;Normalization&#xff09;代码实现 3. 主成分分析&#xff08;Principal Component Analysis, PCA&#xff09;实现步骤代码实现 4. 白化&#xf…...

vue项目中渲染markdown并处理报错

前言&#xff1a;想在vue项目中渲染markdown并处理报错问题 有以下几种方式&#xff1a; 1、使用第三方Markdown插件 2、通过Markdown转HTML工具 3、使用Vue组件处理Markdown 一、首先第一种&#xff1a;使用第三方Markdown插件 安装vue-markdown插件 或者 markdown-it&#xf…...

Vue3.5 企业级管理系统实战(十七):角色管理

本篇主要探讨角色管理功能&#xff0c;其中菜单权限这里先不实现&#xff0c;后续在菜单管理中再进行实现。接口部分依然是使用 Apifox mock 的。 1 角色 api 在 src/api/role.ts 中添加角色相关 api&#xff0c;代码如下&#xff1a; //src/api/role.ts import service fro…...

【AI论文】FormalMATH:大型语言模型形式化数学推理能力基准测试

摘要&#xff1a;正式的数学推理仍然是人工智能面临的一个关键挑战&#xff0c;受到现有基准在范围和规模上的限制。 为了解决这个问题&#xff0c;我们提出了FormalMATH&#xff0c;这是一个大规模的Lean4基准&#xff0c;包含5560个经过形式验证的问题&#xff0c;这些问题涵…...

9-4 USART串口数据包

HEX数据包的接收 研究几个小问题 1.包头包尾和数据载荷重复的问题 这里定义FF为包头&#xff0c;FE为包尾&#xff0c;如果我传输的数据本身就是FF和FE怎么呢&#xff1f;那这个问题确实存在&#xff0c;如果数据和包头包尾重复&#xff0c;可能会引起误判。我们有以下几种解…...

Babylon.js学习之路《 前言:为什么要学习Babylon.js 》

文章目录 引言&#xff1a;3D 开发在 Web 中的崛起为什么需要 Web 3D 开发&#xff1f;当选火热的应用场景数据表达方式的改变 Web 3D 的独特优势跨平台与零安装开发成本低即时更新与传播便捷 WebGL 的定位与挑战WebGL 是什么&#xff1f;WebGL 的直接使用痛点 为什么需要 Baby…...

今年我国已发生三级以上地震318次

快科技5月6日消息&#xff0c;根据中国地震台网的统计&#xff0c;今年以来&#xff08;截至4月30日&#xff09;&#xff0c;我国共发生三级以上地震318次&#xff0c;其中3.0-3.9级248次&#xff0c;4.0-4.9级61次&#xff0c;5.0-5.9级7次&#xff0c;6.0-6.9级2次&#xff…...

在与大语言模型交互中的礼貌现象:技术影响、社会行为与文化意义的多维度探讨

概述 关于是否值得对 AI 保持礼貌的公众意见&#xff0c;几乎和咖啡或红酒的最新研究结果一样频繁变化——这个月被推崇备至&#xff0c;下个月又受到质疑。即便如此&#xff0c;越来越多的用户现在在提示语中加入“请”或“谢谢”&#xff0c;这不仅仅是因为习惯&#xff0c;…...

Java后端开发day42--IO流(二)--字符集字符流

&#xff08;以下内容全部来自上述课程&#xff09; 拓展. try…catch异常处理&#xff08;能看懂&#xff09; 接口&#xff1a;AutoCloseable 特点&#xff1a;特定的情况下&#xff0c;可以自动释放资源 注意&#xff1a;只有实现了AutoCloseable接口的类&#xff0c;才能…...

【HarmonyOS 5】鸿蒙发展历程

【HarmonyOS 5】鸿蒙发展历程 一、鸿蒙 HarmonyOS 版本年代记 鸿蒙 1.0&#xff1a; 2019 年 8 月 9 日&#xff0c;华为在开发者大会上正式发布鸿蒙 1.0 系统&#xff0c;这一版本首次应用于华为荣耀智慧屏产品中&#xff0c;标志着华为正式进军操作系统领域。该版本初步展现…...

使用蚁群算法求解VRPTW问题

这里写目录标题 蚁群优化算法Python实现ACO求解VRPTW问题Java实现ACO求解VRPTW问题蚁群优化算法 蚁群算法(ACO)适合求解带时间窗的车辆路径优化问题(VRPTW),主要基于其仿生智能机制与问题特性的深度契合,具体体现在以下六个方面: 时间窗约束的自然映射 信息素导向与时间…...

内存的位运算

示例&#xff1a;提取和设置标志位 假设我们有一个32位的整数&#xff0c;其中不同的位代表不同的标志。例如&#xff1a; 位0&#xff1a;是否开启日志&#xff08;0表示关闭&#xff0c;1表示开启&#xff09; 位1&#xff1a;是否启用调试模式&#xff08;0表示禁用&#…...

高性能网络优化:深入解析忙轮询(Busy Polling)技术

在现代高性能网络应用中,如何降低数据包处理延迟、提升吞吐量是开发者与系统工程师的核心挑战之一。传统的“中断驱动”模式在高负载场景下表现不佳,而忙轮询(Busy Polling) 作为一种优化技术,通过主动轮询机制显著改善网络性能。本文将从原理、实现到实践,全面解析忙轮询…...

Linux grep 命令详解及示例大全

文章目录 一、基本语法二、常用选项及示例1. 基本匹配&#xff1a;查找包含某字符串的行2. 忽略大小写匹配 -i3. 显示行号 -n4. 递归查找目录下的文件 -r 或 -R5. 仅显示匹配的字符串 -o6. 使用正则表达式 -E&#xff08;扩展&#xff09;或 egrep7. 显示匹配前后行 -A, -B, -C…...

前端知识-hook

React 的生命周期管理被称为 Hook 技术&#xff0c;源于其设计哲学与实现机制中“钩入”组件运行流程的特性。这一命名既是对传统编程中“钩子”&#xff08;Hook&#xff09;概念的延伸&#xff0c;也体现了 React 对函数式组件的逻辑注入能力。以下从多个维度解析其关联性&am…...

uv全功能更新:统一管理Python项目、工具、脚本和环境的终极解决方案

花下猫语&#xff1a;uv 项目自发布起就大受欢迎&#xff0c;目前 Github star 52.6 K&#xff0c;远超过它的同类竞品们。前不久&#xff0c;它的创始人在 X 上披露了一组惊人的数据&#xff1a;uv 曾占据了 PyPI 超过 20% 的流量&#xff0c;用户每天通过它发起约 4-5 亿次下…...

Redis 使用及命令操作

文章目录 一、基本命令二、redis 设置键的生存时间或过期时间三、SortSet 排序集合类型操作四、查看中文五、密码设置和查看密码的方法六、关于 Redis 的 database 相关基础七、查看内存占用 一、基本命令 # 查看版本 redis-cli --version 结果&#xff1a;redis-cli 8.0.0red…...

ROS2:自定义接口文件(无废话)

目录 一、ROS2接口文件定义二、创建接口文件步骤三、验证是否创建成功&#xff0c;以及自定义接口文件的使用 一、ROS2接口文件定义 ROS2中接口文件的格式根据通信的类型可以分为三种&#xff1a; 话题通信&#xff1a;.msg文件 常用格式为&#xff1a;[消息类型] 消息名称 #话…...

如何配置 VScode 断点调试Linux 工程代码

1、Windowns 安装WSL 环境 2、VSCode 中 安装 Romote-SSH扩展&#xff0c;进行连接到WSL下的Linux 环境 安装Romote-SSH成功后&#xff0c;在左下角显示 &#xff0c; 点击此图标 出现 “连接到WSL”, 进行连接 显示&#xff0c;则表明链接成功 3、 VSCode 安装 C/C扩展的调试…...

tinyrenderer笔记(Phong光照模型)

tinyrenderer个人代码仓库&#xff1a;tinyrenderer个人练习代码 前言 在前面的渲染中&#xff0c;我们读取模型的 diffuse 纹理&#xff0c;然后根据法线计算模型的颜色。这次我们引入一种新的光照模型—— Phong 光照模型&#xff0c;Phong 光照模型将光照分为了三类&#x…...

Twin Builder 中的电池等效电路模型仿真

电池单元热设计挑战 电池热管理的主要挑战之一是确保温度低于最大工作限值。较高的温度会导致效率降低、加速老化和潜在的安全隐患。工程师必须了解电池产生的热量&#xff0c;才能充分设计冷却系统。 了解和预测电池模块的热行为需要将电池的热损耗与电池单元的电气机械特性…...

SQLark可以支持PostgreSQL了,有哪些新功能?

SQLark&#xff08;百灵连接&#xff09;是一款国产的数据库开发和管理工具&#xff0c;用于快速查询、创建和管理不同类型的数据库系统&#xff0c;支持达梦、Oracle 和 MySQL 数据库。 最新发布的 SQLark V3.4 版本新增了对 PostgreSQL 数据库的支持。我试用了一下&#xff…...

Redis 7.0中5种新特性及实战应用

Redis 7.0引入了多项革命性的新特性&#xff0c;不仅在性能和可靠性方面有所提升&#xff0c;更在功能和使用体验上有了质的飞跃。本文将介绍Redis 7.0的五大关键新特性&#xff0c;可以根据实际情况利用Redis 7.0的强大功能&#xff0c;构建更高效、更可靠的应用系统。 特性一…...

游戏如何应对AssetStudio解包工具

「游戏解包」是指将游戏文件中被压缩或加密的资源提取出来&#xff0c;通过解包工具对资源进行修改、查看或导出。这个过程通常涉及到将游戏客户端中的数据包进行解压&#xff0c;故称为“解包”。 游戏的资源文件包含代码、图片、视频、音频等重要内容。一旦被解密&#xff0…...

UE5 渲染思路笔记(角色)

参考示例 首先是怎么做到辉光只有部分有而整体没有的 使用的是Bloom内的阈值,控制光的溢光量 Threshold&#xff08;阈值&#xff09;&#xff1a;这个参数决定了图像中哪些像素会参与泛光计算。只有那些亮度超过阈值的像素才会触发泛光效果。阈值越低&#xff0c;更多的像素会…...

Sublime Text快速搭建Lua语言运行环境

第一步 先去Sublime Text官网下载安装 Sublime Text - Text Editing, Done Right 第二步 下载lua编译运行程序 Lua - Joe DFs Builds 第三步 在Sublime Text中配置lua运行环境 {"cmd": ["D:/Lua/lua.exe", "$file"], "file_regex"…...

提示词的 嵌入空间优化

提示词的 嵌入空间优化 提示词的 嵌入空间优化的定义 提示词的嵌入空间优化,是指通过技术手段**调整提示词在低维向量空间(嵌入空间)**中的表示,使其更精准地捕捉语义信息、增强语义关联性,或适配特定任务需求,从而提升模型(如大语言模型)对提示词的理解与处理效果。…...

STM32--GPIO

教程 视频 博主教程 STM32系统结构图 GPIO GPIO&#xff08;General Purpose Input/Output&#xff09;是STM32内部的一种外设。 一个STM32芯片内存在多个GPIO外设&#xff0c;每个GPIO外设有16个引脚&#xff1b; 比如GPIOA&#xff1a;PA0~PA15; GPIOB&#xff1a;PB0~…...

npm下载插件无法更新package.json和package-lock.json文件的解决办法

经过多番查证&#xff0c;使用npm config ls查看相关配置等方式&#xff0c;最后发现全局的.npmrc文件的配置多写了globaltrue&#xff0c;去掉就好了 如果参数很多&#xff0c;不知道是哪个参数引起的&#xff0c;先只保留registryhttp://xxx/&#xff0c;试试下载&#xff0…...

ABAQUS三维CT重建插件CT2Model3D V2版本

插件介绍 CT2Model 3D V2.0插件采用Python 3.10研发&#xff0c;适配2024及以上版本的Abaqus软件&#xff0c;具备在Abaqus平台中基于CT断层扫描图像的三维重建功能&#xff0c;插件支持批量导入tif、tiff、png、jpg等格式的图像文件&#xff0c;推动了数字化建模技术与有限元…...

导入飞帆的网页为组件并注入数据驱动

飞帆制作的网页可以作为 Vue 2 组件导入到你自己的网页中使用。 这里我们来试一下。 并且将数据传入这个组件&#xff0c;驱动里面的仪表盘控件。 https://andi.cn/page/622177.html...

C语言的重要知识点☞static关键字

static译为"静态的"&#xff0c;该关键字可以修饰以下内容&#xff1a; 修饰局部变量修饰全局变量修饰函数 在讲解static的具体作用前需要先知道"作用域"以及"生命周期"的概念&#xff1a; 作用域&#xff1a; 作用域是一个程序设计概念&#…...

unordered_map和unordered_set的设计

#pragma once #include"HashTable.h" namespace aqc {template<class K,class V,class HashHashFunc<K>>class unordered_map{public:struct MapKeyOfT{const K& operator()(const pair<K, V>& kv)//pair对象是const返回值也得是const{ret…...

Servlet--快速入门及HTTP概述

Servlet概述 Servlet&#xff1a;server applet,是用Java编写的服务器端程序&#xff0c;其主要功能在于交互式的浏览和修改数据,生成动态web内容,一般来说,Servlet是指实现了这个Servlet接口的类 在Java中&#xff0c;Servlet是用于创建动态Web内容的服务器端组件。 Servle…...

【LeetCode Hot100 | 每日刷题】二叉树的层序遍历

题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例 2&a…...

编码器型与解码器型语言模型的比较

编码器型与解码器型语言模型的比较 1. 引言 自然语言处理&#xff08;NLP&#xff09;领域近年来取得了革命性进展&#xff0c;这在很大程度上归功于基于Transformer架构的语言模型。在这一技术生态中&#xff0c;编码器型&#xff08;Encoder-only&#xff09;和解码器型&am…...

Java 函数式编程

函数式编程的意义 函数式编程理念强调函数纯粹性和不可变性&#xff0c;这有助于写出更稳定、更易测试的代码&#xff0c;尤其在并发环境下减少 bug lambda 表达式 import java.util.function.Function;public class Strategize {Function<String, String> getString …...

MySQL初阶:基础增删改查(CRUD)

创建&#xff08;Create&#xff09; 先创建一个表 1&#xff09;单独插入一条 insert into 表名 values &#xff08;列名 类型&#xff09;...&#xff1b; 插入的记录要和表一开始创建记录的类型&#xff0c;个数&#xff0c;结构一样。 如果不一样&#xff0c;就会报错。…...

yolo训练用的数据集的数据结构

Football Players Detection using YOLOV11 可以在roboflow上标注 Sign in to Roboflow 训练数据集只看这个data.yaml 里面是train的image地址和classnames 每个image一一对应一个label 第一个位是分类&#xff0c;0是classnames[0]对应的物体&#xff0c;现在是cuboid &…...

vue3+ts继续学习

我们再写点东西&#xff0c;这里面都是vue2的语法&#xff0c;应该都能看明白&#xff01;我们写完直接去运行一下代码&#xff01; 发现什么都没有发生&#xff01;为什么呢&#xff1f;因为我们在App.vue中没有引入&#xff01;哈哈哈哈&#xff01;这样就好了&#xff01;注…...

Oracle01-入门

零、文章目录 Oracle01-入门 1、Oracle简介 &#xff08;1&#xff09;数据库基础 数据库基础请参考&#xff1a;https://blog.csdn.net/liyou123456789/article/details/131207068 &#xff08;2&#xff09;Oracle是什么 ORACLE 数据库系统是美国 ORACLE 公司&#xff…...

即开即用,封装 Flask 项目为 exe 文件实操步骤

见字如面&#xff0c;朋友们&#xff01; 嗨&#xff0c;这里是 AIGC 创意人_竹相左边&#xff01; 正如你们所知&#xff0c;我正在通过 AI 自学软硬件工程师&#xff0c;目标是手搓一台可回收火箭玩具&#xff01; 最近&#xff0c;我被《流浪地球 2》中马兆的那句“没有硬…...

【STM32单片机】#14 PWR电源控制

主要参考学习资料&#xff1a; B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装&#xff1a;STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 目录 PWR…...

FastComposer论文问题与解决

在FastComposer中&#xff0c;跨注意力定位监督&#xff08;Cross-Attention Localization Supervision&#xff09; 的实现是通过以下步骤完成的&#xff0c;核心思想是利用分割掩码约束扩散模型中跨注意力图的分布&#xff0c;确保每个主体的特征仅影响图像中对应的区域。具体…...

51单片机同一个timer 作为定时器和波特率发生器么?

在51单片机中&#xff0c;同一个Timer&#xff08;定时器&#xff09;不能同时作为普通定时器和波特率发生器。这是因为这两种功能都需要对Timer的寄存器进行配置和操作&#xff0c;而它们的配置要求是冲突的。具体来说&#xff1a; 1. 普通定时器功能 配置要求&#xff1a;需…...

爱情的本质是什么--deepseek

爱情的本质是一个跨越生物学、心理学、哲学和社会学的复杂命题。不同学科视角下&#xff0c;爱情呈现出多层次的真相&#xff0c;但核心可以归结为&#xff1a; “爱情是进化塑造的生存策略、神经化学的短暂狂欢&#xff0c;以及人类对抗存在孤独的精神创造。” 以下从四个维…...

Leetcode 刷题记录 07 —— 链表

本系列为笔者的 Leetcode 刷题记录&#xff0c;顺序为 Hot 100 题官方顺序&#xff0c;根据标签命名&#xff0c;记录笔者总结的做题思路&#xff0c;附部分代码解释和疑问解答。 01 相交链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* …...

Android View#post()源码分析

文章目录 Android View#post()源码分析概述onCreate和onResume不能获取View的宽高post可以获取View的宽高总结 Android View#post()源码分析 概述 在 Activity 中&#xff0c;在 onCreate() 和 onResume() 中是无法获取 View 的宽高&#xff0c;可以通过 View#post() 获取 Vi…...