深入探索进程间通信:System V IPC的机制与应用
目录
1、System V概述
2.共享内存(shm)
2.1 shmget — 创建共享内存
2.1.2 ftok(为shmmat创建key值)
2.1.3 为什么一块共享内存的标志信息需要用户来传递
2.2 shmat — 进程挂接共享内存
2.3 shmdt — 断开共享内存连接
2.4 shmctl — 删除共享内存
2.5 命令行查看共享内存
2.6 使用命令释放共享内存资源
2.7. 优缺点
2.8 管道和共享内存的比较(为什么共享内存是最快的)
3 消息队列的原理与概念
4 信号量
4.1 储备知识
4.2 原理与概念
1、System V概述
在Linux系统下,System V指的是一套由AT&T开发的UNIX操作系统版本及其相关的进程间通信(IPC)机制。
System V是UNIX操作系统的一个重要分支,它提供了一套丰富的系统调用和进程间通信机制。与BSD等其他UNIX版本相比,System V在IPC机制方面有着显著的不同和优势。
System V提供了三种主要的IPC机制,包括:
- 共享内存(Shared Memory)
- 消息队列(Message Queues)
- 信号量(Semaphores)
2.共享内存(shm)
进程之间通信的前提都是,通信的进程都可以看到同一份资源。
管道通信是让通信的双方,看到一个操作系统内核管理的缓冲区,通过文件描述符读写数据;。而共享内存则是让进程之间看到一个直接映射到进程地址空间的共享内存区域。
共享内存是有操作系统开辟和维护的,他的生命周期是随着内核的结束而结束的。
共享内存的工作原理基于操作系统的内存管理机制。操作系统为共享内存区域分配一块物理内存,并允许多个进程或线程通过映射这块物理内存到各自的虚拟地址空间来访问它。由于这些进程或线程访问的是同一块物理内存,因此它们可以直接读写这块内存中的数据,而无需进行数据拷贝。
OS中可以存在多个共享内存,共享内存也可以让多组需要通信的进程访问。
2.1 shmget — 创建共享内存
shmget是一个在Linux系统中用于创建或获取共享内存段的系统调用函数。以下是关于shmget的详细解释:
参数说明
- key:共享内存的键值,用于唯一标识共享内存对象。这个键值可以通过ftok函数生成,也可以直接使用IPC_PRIVATE来创建一个新的共享内存对象。
- size:共享内存的大小,以字节为单位。这个大小需要在系统允许的范围内,通常由系统内核参数shmmax和shmmin控制。
- shmflg:标志位,用于指定创建共享内存的权限和行为。下面的表格是常见的标志位
IPC_CREAT 如果共享内存不存在则创建它 IPC_CREAT|IPC_EXCL IPC EXCL单独使用无意义:
如果内存中不存在键值与key值相等的共享内存,则会创建一个新的共享内存
反之,就出错返回
综上: 如果shmget调用成功,必定创建的是一个全新的共享内存IPC CREAT |IPC EXCL|杈限(0xxx) 用来指定创建的共享内存的权限
返回值
- 成功时,shmget返回一个有效的共享内存标识符(shmid),用于后续对共享内存的操作。
- 失败时,shmget返回-1,并将errno设置为相应的错误代码,以指示失败的原因。
2.1.2 ftok(为shmmat创建key值)
ftok
是一个在 Unix 和类 Unix 操作系统(如 Linux)中用于生成一个唯一键值(key)的函数,这个键值通常用于创建或访问 IPC(进程间通信)对象,如消息队列、信号量和共享内存。ftok
函数通过指定的路径名和一个标识符(通常是一个字符)来生成这个键值。
参数说明
pathname
:一个指向文件系统路径名的指针。这个路径名必须指向一个已存在的文件,并且对该文件的访问权限会影响ftok
函数的行为。如果ftok
成功,它不会修改这个文件的内容或属性。proj_id
:一个标识符,通常是一个字符(在 ASCII 范围内,即 0 到 127)。这个标识符与路径名一起用于生成键值。
返回值
- 成功时,
ftok
返回一个唯一的键值(key_t
类型),该键值可以用于创建或访问 IPC 对象。 - 失败时,
ftok
返回(key_t)-1
,并设置errno
以指示错误原因。
2.1.3 为什么一块共享内存的标志信息需要用户来传递
只要通信双方事先约定好了参数,两个进程可以基于相同的文件路劲和项目标识符来生成同一个key值,当它们分别调用shmget函数并传入相同的key,就能够看到同一个共享内存,从而实现进程间通信。如果key是由内核设定,进程之间不知道对方创建共享内存的key值,因为进程具有独立性,从而无法建立通信。
eg:进程A创建共享内存,其key值如果由OS自动生成,进程具有独立性,进程B无法知道进程A创建的共享内存的key值,因此进程B无法访问进程A创建的共享内存,从而无法建立通信。
2.2 shmat — 进程挂接共享内存
hmat是一个在Linux系统中用于进程间通信的函数,特别是在共享内存的使用中扮演着重要角色。
一、函数原型
二、参数说明
- shmid:共享内存标识符,由shmget函数返回。这个标识符用于唯一标识一个共享内存段。
- shmaddr:指定共享内存连接到当前进程的地址空间的起始地址。如果这个参数为NULL,系统会自动选择一个合适的地址。
- shmflg:指定连接共享内存的权限标志。常用的权限标志有SHM_RDONLY(只读连接)等。如果省略此标志,则默认以读写方式附加。
选项 作用 SHM_RDONLY 关联共享内存后只进行读取操作 SHM_RND 若shmaddr不为NULL,则关联地址自动向下调整为SHMLBA的整数倍。公式:shmaddr-(shmaddr%SHMLBA) 0 默认为读写权限
三、返回值
- 成功时,shmat函数返回一个指向共享内存的指针。
- 失败时,返回(void*)-1,并设置相应的错误码。
2.3 shmdt — 断开共享内存连接
shmdt
是一个在 Linux 和其他类 Unix 操作系统中用于进程间通信(IPC)的函数,特别是在共享内存的使用中。它的主要作用是将先前由 shmat
函数附加到进程地址空间的共享内存段分离(detach)出去。
参数
shmaddr
:这是一个指向先前由shmat
返回的共享内存段在进程地址空间中的起始地址的指针。这个地址是shmat
函数成功执行后返回的指针。
返回值
- 成功时,
shmdt
函数返回 0。 - 失败时,返回 -1,并设置相应的错误码。
使用说明
- 在调用
shmdt
函数之后,进程将不再能够通过该指针访问共享内存段。但是,这并不意味着共享内存段被销毁。只要还有其他进程附加(attach)到该共享内存段,或者该共享内存段被标记为持久(persistent),它将继续存在。 - 调用
shmdt
是个好习惯,因为它可以释放进程对共享内存段的引用,从而允许操作系统在必要时回收相关资源。但是,请注意,shmdt
并不销毁共享内存段本身;要销毁共享内存段,需要使用shmctl
函数并指定IPC_RMID
命令。 - 如果进程在退出前没有调用
shmdt
来分离共享内存段,操作系统通常会在进程终止时自动执行这一操作。然而,显式调用shmdt
可以避免潜在的资源泄漏和不必要的系统开销。
错误处理
在使用 shmdt
函数时,可能会遇到以下错误:
- EINVAL:无效的
shmaddr
参数,即该地址不是由shmat
返回的有效共享内存段地址。
当遇到这些错误时,应根据错误码进行相应的处理,例如输出错误信息并采取适当的恢复措施。
2.4 shmctl — 删除共享内存
shmctl是一个在Linux系统中用于控制共享内存的函数。但是普遍用于删除内存。
二、参数说明
-
shmid:共享内存的标识符,该标识符由shmget函数返回。
-
cmd:指定要执行的操作命令。常用的命令有:
IPC_STAT 获取共享内存的状态,将共享内存的shmid_ds结构复制到buf中。 IPC_SET 如果进程有足够的权限,就改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内。 IPC_RMID 删除共享内存段。需要注意的是,该命令实际上不从内核删除共享内存段,而是仅仅把这个段标记为删除。实际删除过程是发生在最后一个使用该共享内存的进程退出或者是解除映射之后。 -
buf:指向shmid_ds结构的指针,用于设置或获取共享内存的属性。当cmd为IPC_STAT或IPC_SET时,需要使用此参数。
三、返回值
若执行成功,shmctl函数返回0;如果失败,返回-1并设置相应的错误码。
四、注意事项
- 在使用shmctl函数之前,必须确保已经成功获取了共享内存的标识符(即shmid)。
- 当使用IPC_RMID命令删除共享内存时,请确保没有其他进程正在使用该共享内存,否则可能会导致未定义的行为。
- 在编写涉及共享内存的程序时,务必注意同步和互斥问题,以避免数据竞争和不一致性。
2.5 命令行查看共享内存
单独使用ipcs
命令时,会默认列出消息队列、共享内存以及信号量相关的信息,若只想查看它们之间某一个的相关信息,可以选择携带以下选项:
- -q:列出消息队列相关信息。
- -m:列出共享内存相关信息。
- -s:列出信号量相关信息。
标题 | 含义 |
---|---|
key | 系统区别各个共享内存的唯一标识 |
shmid | 共享内存的用户层id(句柄) |
owner | 共享内存的拥有者 |
perms | 共享内存的权限 |
bytes | 共享内存的大小 |
nattch | 关联共享内存的进程数 |
status | 共享内存的状态 |
key和shmid的区别:都是确保共享内存的唯一性和可访问性的重要机制。
key在内核中用于标识共享内存,确保其在系统内的唯一性,即:key在内核层面上保证了共享内存的唯一性。
shmid是在成功创建共享内存后由系统返回,用于在用户层面上唯一地标识共享内存,并作为后续对共享内存操作的参数,即:shmid在用户层面上提供了对共享内存的唯一标识和操作接口。
注意: key是在内核层面上保证共享内存唯一性的方式,而shmid是在用户层面上保证共享内存的唯一性,key和shmid之间的关系类似于fd和FILE*之间的的关系。
2.6 使用命令释放共享内存资源
ipcrm [-m|-q|-s] shmid
- 功能:删除已存在的IPC资源对象,包括共享内存、消息队列、信号量集。
2.7. 优缺点
优点:共享内存是所有进程间通信(IPC)方式中速度最快的。
- 减少拷贝次数:在管道通信中,数据通常要经过至少两次拷贝,数据从一个进程的缓冲区写入管道,然后从管道中读取到另一个进程的缓冲区中,这涉及两次数据在不同内存区域之间的复制操作。在共享内存中允许多个进程直接访问同一块内存区域,当一个进程将数据写入到共享内存中,其他进程可以立即看到,最多只会经历一次从进程的用户空间到共享内存的拷贝。
- 直接访问:进程可以直接对共享内存进行读写操作,无需通过OS进行数据中转,这大大减少了内核参与数据传输的开销,提高了通信效率。
缺点:共享内存不提供进程间协同的任何机制。
- 这会导致多个进程同时访问共享内存区域时,出现数据不一致和数据竞争等问题。因为没有内置的同步和互斥手段,不同进程可能在不可预测的时间点对共享内存进行读写操作,从而破坏数据的完整性。例如,一个进程正在写入数据时,另一个进程可能同时在读取,可能会读取到不完整的数据;或者两个进程同时写入,可能会导致数据覆盖混乱。所以需要额外的机制(管道、信号量等)来保证数据的完整性和一致性。
- 进程间协同机制:是确保多个进程在访问公共资源时能够正确地同步、互斥以及协调彼此的操作。协调彼此的操作则涉及更复杂的交互,例如一个进程等待另一个进程完成特定任务后再继续执行。
管道在操作系统中自带协同机制。如:管道的读写操作具有原子性,一次读写要么全部完成,要么全部失败,保证了数据的完整性。同时,阻塞机制也起到了协同的作用,当缓冲区满时,写操作被阻塞,防止数据溢出;当缓冲区为空时,读操作被阻塞,在一定程度上实现了同步和互斥的效果。
2.8 管道和共享内存的比较(为什么共享内存是最快的)
我们先来看看管道通信:
从这张图可以看出,使用管道通信的方式,将一个文件从一个进程传输到另一个进程需要进行四次拷贝操作:
- 服务端将信息从输入文件复制到服务端的临时缓冲区中。
- 将服务端临时缓冲区的信息复制到管道中。
- 客户端将信息从管道复制到客户端的缓冲区中。
- 将客户端临时缓冲区的信息复制到输出文件中。
我们再来看看共享内存通信
从这张图可以看出,使用共享内存进行通信,将一个文件从一个进程传输到另一个进程只需要进行两次拷贝操作:
- 从输入文件到共享内存。
- 从共享内存到输出文件。
所以共享内存是所有进程间通信方式中最快的一种通信方式,因为该通信方式需要进行的拷贝次数最少。
3 消息队列的原理与概念
1.消息队列:一种进程间通信(IPC)的机制,允许多个进程通过发送和接收带有类型的数据块(消息)进行通信,这些消息在队列中按照先进先出(FIFO)的顺序存储。
发送进程将消息添加到队列的末尾,接收进程从队列的头部读取信息。
注:消息队列的生命周期随内核,即:System V IPC资源的生命周期随内核!!!
2.特点
支持异步通信:是指在进行数据传输时,发送方和接收方无需同步,即:它们可以独立的工作,彼此之间无需等待对方的回应。如:发送方发送消息后继续执行,无需等待接收方的回应,接收方可以在任何时间接收消息,同时会触发一个事件来通知发送方,从而达到异步通信的目的。
提供了可靠的消息传递机制,确保了数据不会丢失。如:即使接收方暂时无法处理消息,消息也会保存到队列中,直到接收方读取成功。
灵活的消息格式:消息队列中的消息可以包含不同类型的数据,如:文本、二进制等。
3.基本组件:每个消息队列都有唯一的标识符(msgqid)、消息队列中每个消息都包含一个类型字段和数据字段。
消息中的类型字段可以用于标识消息的类型,以便接收进程可以根据类型来筛选和处理消息,而数据字段则包含实际要传递的数据。
4.发送方和接收方通过使用相同的key值来创建或获取消息队列,它们就可以访问到同一个消息队列,从而实现进程间通信。消息队列特别适用于异步消息传递和任务队列等场景。
4 信号量
4.1 储备知识
1.在多执行流场景下,共享资源可能同时被多个执行流尝试访问、修改,如果不加以保护,这可能会导致数据不一致、资源竞争和死锁等问题。
常见的保护机制主要包括同步和互斥机制。同步机制确保执行流按照预定的顺序进行交互,互斥机制确保共享资源在任何一个时刻只能被一个执行流访问。
2.临界资源:被保护起来且任何时刻只允许一个执行流访问的公共资源,称为临界资源。eg:一个全局变量在多个线程同时读写时,如果不加以保护,可能会出现数据错误,这个全局变量就称为临界资源。
3.临界区:访问临界资源的代码称为临界区。 非临界区:除临界区之外的代码称为非临界区。
程序员需要特别关注和保护临界区,以确保在任何时刻只有一个执行流,能够进入临界区访问临界资源,以防止其他执行流同时访问。
4.保护临界资源,本质是保护临界区,确保在任何时刻只有一个执行流能够访问临界区,从而保护数据的一致性和正确性。
5.原子性:一个操作被认为是原子的,此操作要么完全执行成功,要么完全不执行,不存在中间状态,即:此操作不可分割(一旦开始执行,它必须连续执行完成,中途不能被打断),不能被其他执行流中断。
在并发编程中,原子性用于确保多个线程或进程对共享资源进行操作,不会导致数据不一致、不确定的结果。
4.2 原理与概念
信号量机制本质是对于资源的预订操作,线程或者进程预订了之后,确保未来有一段时间,资源是属于我的。
对于预订资源,会有一个最小单位,资源都是以这个最小单位为整体被使用的。
信号量需要做到:
- 限制进来的进程数(保证每一个进来请求使用资源的进程都有一块资源)
- 合理的分配资源
这里,由于是信号量的前导,我们简单的把信号量理解为一个计数器(是由OS维护的)。
我们这里对于这个信号量的计数器的设计,提出几个问题?
1.计数器能不能简单的设计成一个整型变量?
不行,因为整型变量在经过进程创建之后,任意一个进程对他进行改变的时候,会发生写时拷贝,导致两个进程看到的不是同一个计数器,这样信号量的第一个目的,限制进入的进程数也就失效了。
2.count++和count--不是原子的。
3.申请sem和释放sem来保护临界资源,是规则。这个规则的由来?
这个规则就是,程序员之间规定的规则,再使用多进程访问临界资源的时候,需要代码这样来保护临界资源。
4.所有的进程要访问临界资源,都需要先申请信号量,那么所有进程都需要看到同一个信号量,说明了信号量本身就是一个临界资源。那么我们需要利用临界资源去保护另一个临界资源,为了防止临界资源保护的嵌套,我们就需要保证信号量这个临界资源是安全的。
所以,信号量的申请(++)和信号量的释放(--)这两个操作都是原子的
5.如果,信号量的初始值是1?
那么,这个信号量不就是一个二元信号量(不就是一把锁吗)
6.我们前面提到了信号量也需要合理的分配资源,那么由谁来做呢?
这里,也是由程序员,在代码部分来完成这项目标。
7.pv操作
我们把原子性的申请信号量称为p操作,原子性的释放信号量称为v操作。
相关文章:
深入探索进程间通信:System V IPC的机制与应用
目录 1、System V概述 2.共享内存(shm) 2.1 shmget — 创建共享内存 2.1.2 ftok(为shmmat创建key值) 2.1.3 为什么一块共享内存的标志信息需要用户来传递 2.2 shmat — 进程挂接共享内存 2.3 shmdt — 断开共享内存连接 2.4…...
跨 CA 签发多个证书的 Nginx mTLS 配置
研究过用同一个 CA 签发的服务端和客户端证书的 Nginx mTLS 配置,本文要试验一番服务端和客户端证书由不同 CA 机构签发的情形。这是常有事,比如与客户间采用 mTLS 加密方式,需要文件交付可能是 客户端证书由甲方生成,发送客户端…...
CentOS7 虚拟机 双网卡绑定
一、网卡绑定模式 模式类型特点mode0round-robin(平衡轮询策略)基于per packet方式,轮询往每条链路发送报文。提供负载均衡和容错的能力,当有链路出问题,会把流量切换到正常的链路上。交换机端需要配置聚合口。mode1a…...
设计模式——方法链or流式接口
方法链或流式接口是一种编程模式或设计模式。核心思想是通过返回对象自身的应用,使得可以在一个表达式中连续调用多个方法。 c中实现这种模式 1.基本语法规则 (1)每个可链接的方法都返回对象自身的引用(通常是*this)…...
BioDeepAV:一个多模态基准数据集,包含超过1600个深度伪造视频,用于评估深度伪造检测器在面对未知生成器时的性能。
2024-11-29, 由罗马尼亚布加勒斯特大学创建BioDeepAV数据集,它专门设计来评估最先进的深度伪造检测器在面对未见过的深度伪造生成器时的泛化能力,这对于提高检测器的鲁棒性和适应性具有重要意义。 数据集地址:biodeep 一、研究背景࿱…...
winform 程序添加API接口
假定你有这么一个winform程序,现在有需求开放一个接口,供外部调用,则你可以这样实现 安装需要的依赖包 Microsoft.AspNetCore.App 2.1.34 Microsoft.Extensions.Hosting 8.0.1使用线程在主窗体loading时候启动webhost publi…...
vscode 怎么下载 vsix 文件?
参考:https://marketplace.visualstudio.com/items?itemNameMarsCode.marscode-extension 更好的办法:直接去相关插件的 github repo 下载老版本 https://github.com/VSCodeVim/Vim/releases?page5 或者,去 open-vsx.org 下载老版本 点击这…...
jupyter-lab 环境构建
我平时用来调试各种代码的。 创建环境,安装库 conda create --name jupyterlab python3.12 -y conda activate jupyterlab conda install -c conda-forge jupyterlab nodejs之前用的是3.10的,但是最近安装的时候,发现3.10的python里面的jup…...
Mysql事务常见面试题 -- 事务的特性 ,并发事务问题 , undo_log和redo_log , 分布式事务
一. 事务的特性 ACID 原子性 --> 事务操作被视为一个整体 , 要么全部成功 , 要么全部失败一致性 --> 事务操作前后数据的变化是一致的隔离性 --> 事务的执行不受其他事务的影响持久性 --> 事务执行完毕会对数据永久保存 比如我们在转账的过程中 , A给B转账1000元…...
C# 线程--Thread类
目录 什么是线程? Thread类的定义 创建和启动线程 使用 ThreadStart 委托 使用 ParameterizedThreadStart 委托 Lambda简写 使用线程池(ThreadPool) 使用线程池的优点 使用 ThreadPool 的一般步骤 常用方法 Start() Join() Slee…...
【RK3588 Linux 5.x 内核编程】-内核高分辨率定时器
内核高分辨率定时器 文章目录 内核高分辨率定时器1、高分辨率定时器介绍2、高分辨率定时器API2.1 初始化定时器2.2 启动定时器2.3 停止定时器2.4 改变定时器超时时间2.5 定时器状态检查3、驱动实现4、驱动验证在前面的文章中,我们知道了如果在Linux内核中使用定时器。本文将详…...
论文阅读与源码解析:MogaNet
论文阅读与源码解析:MogaNet: Multi-order Gated Aggregation Network 论文地址:https://arxiv.org/pdf/2211.03295 GitHub项目地址:https://github.com/Westlake-AI/MogaNet 源码:https://github.com/Westlake-AI/MogaNet/blob/…...
长、宽数据表格转换
excel数据读取 使用 readxl 包读取 Excel 文件 library(readxl) 读取 Excel 文件: 使用 read_excel() 函数读取 .xlsx 或 .xls 格式的文件。可以选择指定工作表名或工作表索引。 # 读取 Excel 文件的默认工作表 data <- read_excel("path_to_y…...
华为 Mate 70 系列智能手机将运行不兼容 Android 的鸿蒙
华为宣布其 Mate 70 系列新智能手机将搭载不兼容 Android 的 HarmonyOS Next 操作系统。虽然是基于安卓系统的,但是该分叉树将正式分离。以后将不再兼容安卓系统软件。 HarmonyOS Next 可运行的应用数量仍然远远逊于 Android。华为表示 HarmonyOS Next 获得了逾 1.…...
【Halcon】 derivate_gauss
1、derivate_gauss Halcon中的derivate_gauss算子是一个功能强大的图像处理工具,它通过将图像与高斯函数的导数进行卷积,来计算各种图像特征。这些特征在图像分析、物体识别、图像增强等领域具有广泛的应用。 参数解释 Sigma:高斯函数的标准差,用于控制平滑的程度。Sigma…...
原型模式的理解和实践
引言 在软件开发中,我们经常需要创建具有相同属性或状态的对象。如果采用传统的构造函数或工厂模式来创建对象,那么每次创建对象时都需要重新设置对象的属性,这无疑增加了代码的冗余和复杂性。为了解决这一问题,原型模式ÿ…...
封装loding加载动画的请求
图片 /*** Loading 状态管理类*/ export class Loading {constructor(timer300) {this.value falsethis.timer timer}/*** 执行异步操作并自动管理 loading 状态* param {Promise|Function|any} target - Promise、函数或其他值* returns {Promise} - 返回请求结果*/async r…...
特种设备相关管理A全国通用试题
1.下列()类型的起重机械的定期检验每年1次。 A.机械式停车设备 B.施工升降机 C.门式起重机 D.桅杆式起重机 答案:B 2.压力容器安全技术监察规程中所指的容积,应为( )。 A.应当扣除永久连接在压力容器内部的内件…...
ES语法(一)概括
一、语法 1、请求方式 Elasticsearch(ES)使用基于 JSON 的查询 DSL(领域特定语言)来与数据交互。 一个 ElasticSearch 请求和任何 HTTP 请求一样由若干相同的部件组成: curl -X<VERB> <PROTOCOL>://&l…...
反射的作用
只要不是写死在程序里的对象的创建和调用,都可以用反射来实现。 例如,依据注解或配置信息动态生成并注入对象的需求场景,生成动态代理的需求场景。...
KARE:知识图谱社区级检索,增强 LLM 推理能力的医疗预测框架
KARE:知识图谱社区级检索,增强 LLM 推理能力的医疗预测框架 论文大纲理解要点全流程分析核心模式解法拆解知识图谱社区检索和普通检索有什么本质区别?为什么要同时使用专家LLM和本地LLM?动态知识检索中的评分机制是如何平衡多个因…...
LabVIEW氢气纯化控制系统
基于LabVIEW的氢气纯化控制系统满足氢气纯化过程中对精确控制的需求,具备参数设置、过程监控、数据记录和报警功能,体现了LabVIEW在复杂工业控制系统中的应用效能。 项目背景 在众多行业中,尤其是石油化工和航天航空领域,氢气作为…...
数据分析案例-笔记本电脑价格数据可视化分析
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
CSS函数
目录 一、背景 二、函数的概念 1. var()函数 2、calc()函数 三、总结 一、背景 今天我们就来说一说,常用的两个css自定义属性,也称为css函数。本文中就成为css函数。先来看一下官方对其的定义。 自定义属性(有时候也被称作CSS 变量或者级…...
Linux网络——传输层
目录 1. 再谈端口号 2. UDP ① UDP 协议的报文 ② UDP 协议报头的本质 3. TCP ① TCP 缓冲区的理解 ② TCP 协议的报文 1. 16位源端口号 && 16位目的端口号 && 4位首部长度 2. 16位窗口大小 3. 32位序号 && 32位确认序号 4. 六个标记位 ③…...
2024年认证杯SPSSPRO杯数学建模A题(第一阶段)保暖纤维的保暖能力全过程文档及程序
2024年认证杯SPSSPRO杯数学建模 A题 保暖纤维的保暖能力 原题再现: 冬装最重要的作用是保暖,也就是阻挡温暖的人体与寒冷环境之间的热量传递。人们在不同款式的棉衣中会填充保暖材料,从古已有之的棉花、羽绒到近年来各种各样的人造纤维。不…...
采药 刷题笔记 (动态规划)0/1背包
P1048 [NOIP2005 普及组] 采药 - 洛谷 | 计算机科学教育新生态 动态规划 0/1背包 的本质在于继承 一行一行更新 上一行是考虑前i个物品的最优情况 当前行是考虑第i1个物品的情况 当前行的最优解 来自上一行和前i个物品的最优解进行比较 如果当前装了当前物品ÿ…...
LabVIEW MathScript工具包对运行速度的影响及优化方法
LabVIEW 的 MathScript 工具包 在运行时可能会影响程序的运行速度,主要是由于以下几个原因: 1. 解释型语言执行方式 MathScript 使用的是类似于 MATLAB 的解释型语言,这意味着它不像编译型语言(如 C、C 或 LabVIEW 本身的 VI&…...
大数据新视界 -- Hive 数据湖架构中的角色与应用(上)(25 / 30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
电脑关机的趣味小游戏——system函数、strcmp函数、goto语句的使用
文章目录 前言一. system函数1.1 system函数清理屏幕1.2 system函数暂停运行1.3 system函数电脑关机、重启 二、strcmp函数三、goto语句四、电脑关机小游戏4.1. 程序要求4.2. 游戏代码 总结 前言 今天我们写一点稍微有趣的代码,比如写一个小程序使电脑关机…...
elasticsearch是如何进行搜索的?
请求与转发 协调节点确定参与搜索的目标索引,及其通过分片路由表确定分片对索引所在分片中选择任意节点并发请求多个分片的副本分片 副本选择策略 副本选择主要考虑 分片健康状态:选择状态为 green 或 yellow 的副本节点负载情况:避免查询…...
【Linux课程学习】:站在文件系统之上理解:软硬链接,软硬链接的区别
🎁个人主页:我们的五年 🔍系列专栏:Linux课程学习 🌷追光的人,终会万丈光芒 🎉欢迎大家点赞👍评论📝收藏⭐文章 Linux学习笔记: https://blog.csdn.net/d…...
如何做好一份技术文档
要做好一份技术文档,你需要遵循以下步骤: 1. 明确文档目标: 确定文档的目的和受众。 了解受众的技术水平和背景,以便调整内容的深度和语言风格。 2. 收集信息: 搜集所有与主题相关的技术细节、数据、图表和…...
优雅关闭进程
原文地址:优雅关闭进程 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 介绍 本文涉及到进程对信号的响应,关于信号的一些基本知识,可以参考往期文章:linux系统信号简介 – 无敌牛 一个进程正常…...
【WEB开发.js】addEventListener事件监听器的绑定和执行次数的问题(小心踩坑)
假设我们有一个按钮,用户点击该按钮后,会选择一个文件,且我们希望每次点击按钮时只触发一次文件处理。下面我会给你一个简单的例子,展示放在函数内部和放在函数外部的区别。 1. 将事件监听器放在函数内部(问题的根源&…...
将 x 减到 0 的最小操作数 C++滑动窗口
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。 如果可以将 x 恰好 减到 0 ,返回 最小操作数 &#x…...
深入解析 C++ 中的 common_reference_with 和 common_with:设计原理与复杂性
在 C 标准库的设计中,类型之间的兼容性和安全性是至关重要的,尤其是在泛型编程中。为了实现高效且安全的类型推导和转换,C 提供了一些复杂的概念和工具来确保不同类型之间能够正确协同工作。common_reference_with 和 common_with 这两个概念…...
从CPU缓存与指令重排序探讨JMM
目录 问题背景 解决思路 hb关系的应用 原子性问题 问题背景 1. 编译器和CPU优化: 编译器和CPU为了提升单线程程序的性能,会对代码进行优化,如指令重排序、延迟计算等。这些优化在单线程环境下不会影响程序的最终结果,但在多线…...
ETSI EN 300328 标准的一些笔记
ETSI - European Telecommunications Standards Institute 欧洲电信标准化协会 ETSI EN 300328 是欧洲协调标准,此标准适用于工作在2.4G频段范围内运行的宽频传输系统和设备的无线电频谱。 例如 WIFI、Zigbee、蓝牙、 (国内的星闪)。不涵盖UWB。 符合了EN 300328标…...
各大浏览器(如Chrome、Firefox、Edge、Safari)的对比
浏览器如Chrome、Firefox、Edge等在功能、性能、隐私保护等方面各有特点。以下是对这些浏览器的详细对比,帮助你选择合适的浏览器。 1. Google Chrome 市场份额:Chrome是目前市场上最流行的浏览器,约占全球浏览器市场的65%以上。 性能&#…...
AD7606使用方法
AD7606是一款8通道最高16位200ksps的AD采样芯片。5V单模拟电源供电,真双极性模拟输入可以选择10 V,5 V两种量程。支持串口与并口两种读取方式。 硬件连接方式: 配置引脚 引脚功能 详细说明 OS2 OS1 OS2 过采样率配置 000 1倍过采样率 …...
双向长短期记忆(Bi-LSTM)神经网络介绍
长短期记忆(Long Short-Term Memory, LSTM)神经网络: 1.是Hochreiter和Schmidhuber设计的循环神经网络(Recurrent Neural Network, RNN)的改进版本。LSTM模型借鉴了人类大脑的选择性输入和选择性遗忘机制,获取序列中的关键信息,遗忘和当前预测…...
openGauss开源数据库实战十八
文章目录 任务十八 openGauss逻辑结构:构:用户和权眼管理任务目标实施步骤一、准备工作二、用户和角色管理1.使用CREATE USER语句创建用户2.使用CREATE ROLE语句创建用户3.删除用户和角色 三、权限管理1.系统权限清理工作 任务十八 openGauss逻辑结构:构:用户和权眼管理 任务目…...
JVM 性能调优 -- JVM 调优常用网站
前言: 上一篇分享了 JDK 自带的常用的 JVM 调优命令和图形化界面工具,本篇我们分享一下常用的第三方辅助 JVM 调优网站。 JVM 系列文章传送门 初识 JVM(Java 虚拟机) 深入理解 JVM(Java 虚拟机) 一文搞…...
现在的电商风口已经很明显了
随着电商行业的不断发展,直播带货的热潮似乎正逐渐降温,而货架电商正成为新的焦点。抖音等平台越来越重视货架电商,强调搜索功能的重要性,预示着未来的电商中心将转向货架和搜索。 在这一转型期,AI技术与电商的结合为…...
基于AT89C52单片机的电子时钟与温湿度检测系统
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
Wwise SoundBanks内存优化
1.更换音频格式为Vorbis 2.停用多余的音频,如Random Container的随机脚步声数量降为2个 3.背景音乐勾选“Stream”。这样就让音频从硬盘流送到Wwise,而不是保存在内存当中,也就节省了内存 4.设置最大发声数Max Voice Instances 5.设置音频…...
Next.js 独立开发教程(十三):错误处理(Error Handling)
系列文章目录 Next.js 开发教程(一):入门指南-CSDN博客 Next.js 开发教程(二):从零构建仪表盘应用-CSDN博客 Next.js 开发教程(三):CSS 样式的完整指南-CSDN博客 Next.js 独立开发教程&…...
【Halcon】边缘检测算子汇总(一)
frei_amp 功能:使用Frei-Chen算法检测图像的边缘振幅。 参数: 输入图像(Image):待处理的原始图像。输出梯度图像(ImageEdgeAmp):经过Frei-Chen算法处理后的边缘振幅图像。工作原理:frei_amp算子通过计算图像一阶导数的近似值来检测边缘。它使用两个特定的滤波器掩模(…...
前端开发中Token存储:选择Cookie还是localStorage?
在现代前端开发领域,用户身份验证与状态管理不可或缺,而 token 作为身份验证机制的核心要素,对保障用户信息安全至关重要。然而,token 的存储方式对应用安全性和用户体验有着直接影响。本文将从安全性、便捷性和使用场景等维度,深度剖析在 Cookie 和 localStorage 中选择存…...