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

Linux/AndroidOS中进程间的通信线程间的同步 - 共享内存

在之前的文章中介绍了允许无关进程共享内存区域以便执行 IPC 的技术:共享文件映射。但他存在一些不足。

  • 使用一个共享文件映射来进行 IPC 要求创建一个磁盘文件,即使无需对共享区域进行持久存储也需要这样做。
  • 除此之外,这种技术还会带来一些文件 I/O 开销。

由于存在这些不足,所以 POSIX.1b 定义了一组新的共享内存 API:POSIX 共享内存。

1 概述

POSIX 共享内存能够让无关进程共享一个映射区域而无需创建一个相应的映射文件。Linux 从内核 2.4 起开始支持 POSIX 共享内存。

Linux 使用挂载于/dev/shm 目录下的专用 tmpfs 文件系统1。这个文件系统具有内核持久性——它所包含的共享内存对象会一直持久,即使当前不存在任何进程打开它,但这些对象会在系统关闭之后丢失。

要使用 POSIX 共享内存对象需要完成下列任务。

  1. 使用 shm_open()函数打开一个与指定的名字对应的对象。shm_open()函数与 open()系统调用类似,它会创建一个新共享对象或打开一个既有对象。作为函数结果,shm_open()会返回一个引用该对象的文件描述符。
  2. 将上一步中获得的文件描述符传入 mmap()调用2并在其 flags 参数中指定 MAP_SHARED。这会将共享内存对象映射进进程的虚拟地址空间。与 mmap()的其他用法一样,一旦映射了对象之后就能够关闭该文件描述符而不会影响到这个映射。然而,有可能需要将这个文件描述符保持在打开状态以便后续的fstat()和ftruncate()调用使用这个文件描述符。

2 创建共享内存对象

shm_open()函数创建和打开一个新的共享内存对象或打开一个既有对象。传入 shm_open()的参数与传入 open()的参数类似。

#include <fcntl.h>			/*Defines 0*constants */
#include <sys/stat.h>		/* Defines mode constants */
#include<sys/mman.h>int shm_open(const char *name, int oflag, mode_t mode);/*Returns file descriptor on success, or -l on error*/

name 参数标识出了待创建或待打开的共享内存对象。oflag 参数是一个改变调用行为的位掩码,表中对这个参数的取值进行了总结。
在这里插入图片描述
oflag 参数的用途之一是确定是打开一个既有的共享内存对象还是创建并打开一个新对象。

  • 如果 oflag 中不包含 O_CREAT,那么就打开一个既有对象。
  • 如果指定了 O_CREAT,那么在对象不存在时就创建对象。
  • 同时指定 O_EXCL 和 O_CREAT 能够确保调用者是对象的创建者,如果对象已经存在,那么就返回一个错误(EEXIST)。

oflag 参数还表明了调用进程在共享内存对象上的访问模式,其取值为 O_RDONLY 或O_RDWR。剩下的标记值 O_TRUNC 会导致在成功打开一个既有共享内存对象之后将对象的长度截断为零。

在一个新共享内存对象被创建时,其所有权和组所有权将根据调用 shm_open()的进程的有效用户和组 ID 来设定,对象权限将会根据 mode 参数中设置的掩码值来设定。mode 参数能取的位值与文件上的权限位值是一样的。

  • 与 open()系统调用一样,mode 中的权限掩码将会根据进程的 umask来取值。
  • 与 open()不同的是,在调用 shm_open()时总是需要 mode 参数,在不创建新对象时需要将这个参数值指定为 0。

shm_open()返回的文件描述符会设置 close-on-exec 标记(FD_CLOEXEC),因此当程序执行了一个 exec()时文件描述符会被自动关闭。(这与在执行 exec()时映射会被解除的事实是一致的。)

一个新共享内存对象被创建时其初始长度会被设置为 0。这意味着在创建完一个新共享内存对象之后通常在调用 mmap()之前需要调用 ftruncate()来设置对象的大小。在调用完 mmap()之后可能还需要使用 ftruncate()来根据需求扩大或收缩共享内存对象。

在任何时候都可以在 shm_open()返回的文件描述符上使用 fstat()以获取一个 stat结构,该结构的字段会包含与这个共享内存对象相关的信息,包括其大小(st_size)、权限(st_mode)、所有者(st_uid)以及组(st_gid)。使用 fchmod()和 fchown()能够分别修改共享内存对象的权限和所有权。

示例程序
程序提供了一个简单的使用 shm_open()、ftruncate()以及 mmap()的例子。这个程序创建了一个大小通过命令行参数指定的共享内存对象并将该对象映射进进程的虚拟地址空间。这个程序允许使用命令行选项来选择 shm_open()调用使用的标记(O_CREAT 和 O_EXCL)。
下面的例子使用这个程序创建了一个 10000 字节的共享内存对象,然后在/dev/shm 中使用 ls 命令显示出了这个对象。

$ ./pshm_create -c /demo_shm 10000
$ ls -l /dev/shm/
total 0
-rw------- 1 dockdroid dockdroid 10000 May  7 11:03 demo_shm
/* pshm/pshm_create.cCreate a POSIX shared memory object with specified size and permissions.Usage as shown in usageError().创建一个 POSIX 共享内存对象
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "tlpi_hdr.h"static void
usageError(const char *progName)
{fprintf(stderr, "Usage: %s [-cx] shm-name size [octal-perms]\n", progName);fprintf(stderr, "    -c   Create shared memory (O_CREAT)\n");fprintf(stderr, "    -x   Create exclusively (O_EXCL)\n");exit(EXIT_FAILURE);
}int
main(int argc, char *argv[])
{int flags, opt, fd;mode_t perms;size_t size;void *addr;flags = O_RDWR;while ((opt = getopt(argc, argv, "cx")) != -1) {switch (opt) {case 'c':   flags |= O_CREAT;           break;case 'x':   flags |= O_EXCL;            break;default:    usageError(argv[0]);}}if (optind + 1 >= argc)usageError(argv[0]);size = getLong(argv[optind + 1], GN_ANY_BASE, "size");perms = (argc <= optind + 2) ? (S_IRUSR | S_IWUSR) :getLong(argv[optind + 2], GN_BASE_8, "octal-perms");/* Create shared memory object and set its size */fd = shm_open(argv[optind], flags, perms);if (fd == -1)errExit("shm_open");if (ftruncate(fd, size) == -1)errExit("ftruncate");/* Map shared memory object */if (size > 0) {addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (addr == MAP_FAILED)errExit("mmap");}exit(EXIT_SUCCESS);
}

3 使用共享内存对象

示例程序演示了如何使用一个共享内存对象将数据从一个进程传输到另一个进程中。程序将其第二个命令行参数中包含的字符串复制到了一个名字通过其第一个命令行参数指定的既有共享内存对象中。在映射这个对象和执行复制之前,这个程序使用了 ftruncate()来将共享内存对象的长度设置为与待复制的字符串的长度一样。

/* pshm/pshm_write.cUsage: pshm_write shm-name stringCopy 'string' into the POSIX shared memory object named in 'shm-name'.将数据复制进一个 POSIX 共享内存对象See also pshm_read.c.
*/
#include <fcntl.h>
#include <sys/mman.h>
#include "tlpi_hdr.h"int
main(int argc, char *argv[])
{int fd;size_t len;                 /* Size of shared memory object */char *addr;if (argc != 3 || strcmp(argv[1], "--help") == 0)usageErr("%s shm-name string\n", argv[0]);fd = shm_open(argv[1], O_RDWR, 0);      /* Open existing object */if (fd == -1)errExit("shm_open");len = strlen(argv[2]);if (ftruncate(fd, len) == -1)           /* Resize object to hold string */errExit("ftruncate");printf("Resized to %ld bytes\n", (long) len);addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);if (addr == MAP_FAILED)errExit("mmap");if (close(fd) == -1)                    /* 'fd' is no longer needed */errExit("close");printf("copying %ld bytes\n", (long) len);memcpy(addr, argv[2], len);             /* Copy string to shared memory */exit(EXIT_SUCCESS);
}

下面示例程序中在标准输出上显示了名字通过其命令行参数指定的既有共享内存对象中的字符串。在调用 shm_open()之后,这个程序使用了 fstat()来确定共享内存的大小并在映射该对象的 mmap()调用中和打印这个字符串的 write()调用中使用这个值。

/* pshm_read.cUsage: pshm_read shm-nameCopy the contents of the POSIX shared memory object named in'name' to stdout.See also pshm_write.c.
*/
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "tlpi_hdr.h"int
main(int argc, char *argv[])
{int fd;char *addr;struct stat sb;if (argc != 2 || strcmp(argv[1], "--help") == 0)usageErr("%s shm-name\n", argv[0]);fd = shm_open(argv[1], O_RDONLY, 0);    /* Open existing object */if (fd == -1)errExit("shm_open");/* Use shared memory object size as length argument for mmap()and as number of bytes to write() */if (fstat(fd, &sb) == -1)errExit("fstat");addr = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);if (addr == MAP_FAILED)errExit("mmap");if (close(fd) == -1)                    /* 'fd' is no longer needed */errExit("close");write(STDOUT_FILENO, addr, sb.st_size);write(STDOUT_FILENO, "\n", 1);exit(EXIT_SUCCESS);
}

下面的 shell 会话演示了如何使用示例程序。首先创建一个长度为零的共享内存对象。

$ ./pshm_create -c /demo_shm 0
$ ls -l /dev/shm/
total 0
-rw------- 1 dockdroid dockdroid 0 May  7 11:27 demo_shm

然后将一个字符串复制进共享内存对象。

$ ./pshm_write /demo_shm "hello"
Resized to 5 bytes
copying 5 bytes
$ ls -l /dev/shm/
total 4
-rw------- 1 dockdroid dockdroid 5 May  7 11:28 demo_shm

从上面的输出中可以看出这个程序重新设定了共享内存对象的大小使之具备足够的空间来存储指定的字符串。

最后显示共享内存对象中的字符串。

$ ./pshm_read /demo_shm
hello

应用程序通常需要使用一些同步技术来让进程协调它们对共享内存的访问。在这里给出的示例 shell 会话中,这种协调是通过用户一个一个运行这些程序来完成的。通常,应用程序会使用一种同步原语(如信号量)来协调对共享内存对象的访问。

4 删除共享内存对象

POSIX 共享内存对象具备内核持久性,即它们会持续存在直到被显式删除或系统重启。当不再需要一个共享内存对象时就应该使用 shm_unlink()删除它。

#include <sys/mman.h>
int shm unlink(const char *name);

shm_unlink()函数会删除通过 name 指定的共享内存对象。删除一个共享内存对象不会影响对象的既有映射(它会保持有效直到相应的进程调用 munmap()或终止),但会阻止后续的shm_open()调用打开这个对象一旦所有进程都解除映射这个对象,对象就会被删除,其中的内容会丢失
示例程序使用 shm_unlink()来删除通过程序的命令行参数指定的共享内存对象。

/* pshm_unlink.cUsage: pshm_unlink shm-nameRemove the POSIX shared memory object identified by 'name'使用 shm_unlink()来断开链接一个 POSIX 共享内存对象
*/
#include <fcntl.h>
#include <sys/mman.h>
#include "tlpi_hdr.h"int
main(int argc, char *argv[])
{if (argc != 2 || strcmp(argv[1], "--help") == 0)usageErr("%s shm-name\n", argv[0]);if (shm_unlink(argv[1]) == -1)errExit("shm_unlink");exit(EXIT_SUCCESS);
}

5 共享内存 API 比较

到现在为止已经了解了两种不同的在无关进程间共享内存区域的技术。

  • 共享文件映射。
  • POSIX 共享内存对象。

下列要点适用于所有这些技术。

  • 它们提供了快速 IPC,应用程序通常必须要使用一个信号量(或其他同步原语)来同步对共享区域的访问。
  • 一旦共享内存对象区域被映射进进程的虚拟地址空间之后,它就与进程的内存空间中的其他部分无异了。
  • 系统会以类似的方式将共享内存区域放置进进程的虚拟地址空间中。Linux 特有的/proc/PID/maps 文件会列出与所有种类的共享内存区域相关的信息。
  • 假设不会将一个共享内存区域映射到一个固定的地址处,那么就需要确保所有对区域中的位置的引用会使用偏移量来表示,而不是使用指针来表示,这是因为这个区域在不同进程中所处的虚拟地址可能是不同的。
  • 操作虚拟内存区域的函数可被应用于使用这些技术中任意一项技术创建的共享内存区域。

  1. 系统上 POSIX 共享内存区域占据的内存总量受限于底层的 tmpfs 文件系统的大小。这个文件系统通常会在启动时使用默认大小(如 256MB)进行挂载。如果有必要的话,超级用户能够通过使用命令 mount –o remount,size=重新挂载这个文件系统来修改它的大小。 ↩︎

  2. 使用 POSIX 共享内存对象需要两步式过程(shm_open()加上 mmap())而没有使用单个函数来执行两项任务是因为历史原因。在 POSIX 委员会增加这个特性时,mmap()调用已经存在了。实际上,这里所需要做的事情是使用shm_open()调用替换open()调用,其中的差别是使用 shm_open()无需在一个基于磁盘的文件系统上创建一个文件。 ↩︎

相关文章:

Linux/AndroidOS中进程间的通信线程间的同步 - 共享内存

在之前的文章中介绍了允许无关进程共享内存区域以便执行 IPC 的技术&#xff1a;共享文件映射。但他存在一些不足。 使用一个共享文件映射来进行 IPC 要求创建一个磁盘文件&#xff0c;即使无需对共享区域进行持久存储也需要这样做。除此之外&#xff0c;这种技术还会带来一些…...

ES6入门---第三单元 模块七: Proxy的使用+Reflect的使用

proxy: 代理 扩展(增强)对象、方法(函数)一些功能 比如: Vue Vue.config.keyCodes.enter65 Proxy作用: 比如vue中拦截 预警、上报、扩展功能、统计、增强对象等等 proxy是设计模式一种&#xff0c; 代理模式 语法: new Proxy(target, handler); …...

【JAVA】BigDecimal判断是否为0, / by zero的问题修复

bug场景 我要处理一个任务完成率的计算&#xff0c;任务完成率pct 实际值 real / 任务值 task 进入计算前&#xff0c;我需要判断task是否为空&#xff0c;或者为0&#xff0c;防止除法出错。 之前使用了equal方法 if(!task.equals(BigDecimal.ZERO))//开始计算因为刚开始测…...

从 “机器人 +“ 到 “+ 机器人“:算力政策撬动的产业生态革命

在深圳光明科学城的云端算力平台上&#xff0c;数据以每秒千万次的速度流动&#xff0c;这里每年发放的 600 万元算力补贴&#xff0c;正如同催化剂般激活着人形机器人产业的深层变革。当广东将 "算力券" 政策精准嵌入珠三角制造体系&#xff0c;一场从 "单机智…...

如何在24G显存机器上搭建一个超过gpt效果的DeepSeek-R1?

DeepSeek-R1蒸馏模型概述与应用指南 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/5af5a8b13de14bd1a95837bbf1ccaf2a.png#pic_center) 引言 DeepSeek-R1作为一款先进的AI推理模型&#xff0c;在性能上已超越GPT-4o和Claude-3.5等主流开源模型。为满足更广泛应用…...

seamless_communication,facebook推出的开源语音翻译项目

Seamless Communication‌是由Facebook Research开发的一个开源项目&#xff0c;旨在提供先进的语音和文本翻译功能&#xff0c;支持多国语音。 今天试着来复现下。 1、首先下载代码。 git clone https://github.com/facebookresearch/seamless_communication 2、按照步骤执…...

C++从入门到实战(十二)详细讲解C++如何实现内存管理

C从入门到实战&#xff08;十二&#xff09;详细讲解C如何实现内存管理 前言一、C内存管理方式1. new/delete操作内置类型2. 异常与内存管理的联系&#xff08;简单了解&#xff09;3. new和delete操作自定义类型 二、 operator new与operator delete函数&#xff08;重点&…...

console-chat-gpt开源程序是用于 AI Chat API 的 Python CLI

​一、软件介绍 文末提供程序和源码下载 console-chat-gpt开源程序是用于 AI Chat API 的 Python CLI&#xff0c;与 AI 模型聊天的终极 CLI 伴侣&#xff0c;直接从命令行享受与 OpenAI、MistralAI、Anthropic、xAI、Google AI、DeepSeek、阿里巴巴、Inception 或 Ollama 托管…...

影刀RPA开发-程序备注说明的必要性

1. 备注指令的调用 1.1 指令搜索 搜索出备注指令后&#xff0c;添加到代码框中 1.2 快捷输入 在代码框中&#xff0c;输入指令关键字&#xff0c;可以快速展示出相关指令 2.备注指令内容设置 备注信息要依据代码执行的功能书写 尽量写明该语句或该段落代码的功能作用 单行…...

第十节:图像处理基础-图像算术运算 (加法、减法、混合)

引言 在计算机视觉领域&#xff0c;图像算术运算是最基础却至关重要的核心技术。无论是实现简单的图片合成、开发智能监控系统&#xff0c;还是构建复杂的医学影像分析工具&#xff0c;加减运算和混合操作都扮演着关键角色。OpenCV作为最流行的计算机视觉库&#xff0c;提供了…...

如何使用UGUI的EventTrigger

前言 在 Unity 的 UGUI 系统中,EventTrigger 是一个强大的组件,允许开发者监听和处理多种 UI 交互事件。以下是详细的使用方法、示例代码、优缺点分析以及注意事项。 一、EventTrigger 基本用法 1. 添加 EventTrigger 组件 在 Unity 编辑器中选中 UI 对象(如 But…...

5G赋能农业物联网:智能化种植的新纪元

5G赋能农业物联网&#xff1a;智能化种植的新纪元 在农业领域&#xff0c;精准化、智能化已成为现代农业发展的方向。而5G的出现&#xff0c;让农业物联网&#xff08;Agri-IoT&#xff09;突破了传统的瓶颈&#xff0c;真正实现了实时监测、高效数据传输、智能化决策&#xf…...

LeetCode 热题 100 64. 最小路径和

LeetCode 热题 100 | 64. 最小路径和 大家好&#xff0c;今天我们来解决一道经典的动态规划问题——最小路径和。这道题在 LeetCode 上被标记为中等难度&#xff0c;要求找到从网格的左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 问题描述 给定一个包含非负…...

精益数据分析(45/126):媒体网站商业模式的深度剖析与挑战应对

精益数据分析&#xff08;45/126&#xff09;&#xff1a;媒体网站商业模式的深度剖析与挑战应对 在创业和数据分析的领域中&#xff0c;探索不同商业模式的运作机制和关键要点是提升业务能力的重要途径。今天&#xff0c;我们依旧带着共同进步的目标&#xff0c;深入研读《精…...

学习Linux的第四天

今天我们来学习Linux的网络配置&#xff0c;以及链表的知识开个小头 三种网络配置模式 桥接模式&#xff08;用的最多&#xff09; 2.Nat模式 3. 仅主机模式&#xff08;Nat模式的功能外&#xff0c;只能在局域网通信&#xff0c;不能访问外网&#xff09; 桥接模式&#xf…...

AGV导航控制器技术方案——基于EFISH-SBC-RK3576/SAIL-RK3576的国产化革新‌(新一代工业级自主可控解决方案)‌

一、方案核心架构 ‌1. 硬件拓扑设计‌ ‌主控单元‌&#xff1a;SAIL-RK3576核心板&#xff08;八核A72A53M0异构架构&#xff09;‌传感器层‌&#xff1a; 双激光雷达&#xff08;RS-LiDAR-16线 SICK TIM240&#xff09;9轴IMU&#xff08;BMI088&#xff09; 轮式编码器&…...

ISCC 2025练武题 WP部分

总结 垃圾比赛&#xff0c;垃圾题目&#xff0c;纯脑洞题&#xff0c;技术好不好没得关系&#xff0c;就看你脑洞大不大。 web里塞misc&#xff0c;re里塞misc真是牛逼他妈给牛逼开门牛逼到家。 逆天平台&#xff0c;卡的一批&#xff0c;靶机还是公用的&#xff0c;把flag删…...

mysql:什么是一致性视图(Read View)

一致性视图&#xff08;Read View&#xff09;是 MVCC&#xff08;多版本并发控制&#xff09;中的核心概念&#xff0c;用于实现事务隔离性。 它是一个逻辑概念&#xff0c;让事务在读取数据时看到特定时间点的数据库快照&#xff0c;而不受其他事务并发修改的影响。 一致性…...

android中背压问题面试题及高质量回答范例

&#x1f3af; 回答的目标是&#xff1a; 表现出你理解背压的本质&#xff08;不是框架知识&#xff0c;而是系统层面的问题&#xff09;。 能清晰讲出几种处理背压的方案&#xff08;理论 实战&#xff09;。 能结合 Android 场景讲具体例子&#xff08;比如 UI 线程、网络…...

【C++】C++11(上)

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; C学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大…...

工具分享:通过滑块拉取CAN报文信号数值自动发送报文

0. 概述 CAN报文发送工具使用wxpython进行开发,配套Excel模板可以通过修改Excel自定义界面展示的信号名称和信号的属性;同时,工具支持导入现场采集的报文数据自动按照配套Excel模板定义的报文发送周期进行模拟发送。 由于是我好几年前开发的作品,一些开发细节也记得不是很…...

android 折叠屏开发适配全解析:多窗口、铰链处理与响应式布局

安卓适配折叠屏指南 折叠屏设备为安卓开发带来了新的机遇和挑战。以下是适配折叠屏的关键要点&#xff1a; 1. 屏幕连续性检测 // 检查设备是否支持折叠屏特性 private fun isFoldableDevice(context: Context): Boolean {return context.packageManager.hasSystemFeature(&…...

Cloudera CDP 7.1.3 主机异常关机导致元数据丢失,node不能与CM通信

问题描述 plaintext ERROR Could not load post-deployment data from /var/run/cloudera-scm-agent/process/ccdeploy_hadoop-conf_etchadoopconf.cloudera.yarn_-8903374259073700469 IOError: [Errno 2] No such file or directory: /var/run/cloudera-scm-agent/proce…...

超越 DeepSeek-R1,英伟达新模型登顶

近日&#xff0c;英伟达发布全新开源模型系列 Llama-Nemotron&#xff0c;凭借卓越性能引发业界关注&#xff0c;有望重塑开源 AI 格局。 该系列在推理能力上超越 DeepSeek-R1&#xff0c;内存效率与吞吐量显著提升。其创新采用合成数据监督微调与强化学习训练&#xff0c;全方…...

centos8.5.2111 更换阿里云源

使用前提是服务器可以连接互联网 1、备份现有软件配置文件 cd /etc/yum.repos.d/ mkdir backup mv CentOS-* backup/ 2、下载阿里云的软件配置文件 wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo 3、清理并重建…...

阿里云平台与STM32的物联网设计

基于阿里云平台与STM32的物联网设计方案可结合硬件选型、通信协议、云端配置及功能实现等多个维度进行设计。以下是综合多个参考案例的详细设计方案&#xff1a; 一、硬件选型与架构设计 主控芯片选择 STM32系列&#xff1a;推荐使用STM32F103&#xff08;如STM32F103ZET6、STM…...

ESP32- 开发笔记- 软件开发 6 蓝牙协议栈 1

1 蓝牙 ESP32 是一款支持蓝牙功能的强大微控制器&#xff0c;ESP-IDF (Espressif IoT Development Framework) 提供了完整的蓝牙开发支持。 1.1 蓝牙模式 ESP32 支持两种蓝牙模式&#xff0c;即同时支持经典蓝牙和低功耗蓝牙。 1.1.1 蓝牙经典 (BT/BDR/EDR) 支持传统蓝牙协…...

python爬虫爬取网站图片出现403解决方法【仅供学习使用】

基于CSDN第一篇文章&#xff0c;Python爬虫之入门保姆级教程&#xff0c;学不会我去你家刷厕所。 这篇文章是2021年作者发表的&#xff0c;由于此教程&#xff0c;网站添加了反爬机制&#xff0c;有作者通过添加cookie信息来达到原来的效果&#xff0c;Python爬虫添加Cookies以…...

利用动态数字孪生:Franka Research 3 机械臂在机器人策略评估中的创新实践——基于Real-is-Sim框架的仿真与现实闭环验证

一、前言&#xff1a; 在机器人技术飞速发展的今天&#xff0c;如何高效、准确地评估机器人在现实世界中的操作策略&#xff0c;成为制约机器人技术进一步突破的关键瓶颈。传统方法往往依赖于耗时且成本高昂的真实世界测试&#xff0c;而模拟环境虽能提供便利&#xff0c;却因…...

Spark-Core(RDD行动算子)

一、RDD行动算子 行动算子就是会触发action的算子&#xff0c;触发action的含义就是真正的计算数据。 1、reduce 函数签名&#xff1a; def reduce(f: (T, T) > T): T 函数说明&#xff1a;聚集 RDD 中的所有元素&#xff0c;先聚合分区内数据&#xff0c;再聚合分区间…...

spark转换算子

在 Apache Spark 中&#xff0c;转换算子&#xff08;Transformation&#xff09;是用于对 RDD&#xff08;弹性分布式数据集&#xff09;进行转换操作的函数。这些操作是惰性的&#xff0c;即在调用转换算子时&#xff0c;Spark 并不会立即执行计算&#xff0c;而是记录下转换…...

hadoop的运行模式

&#xff08;一&#xff09;Hadoop的运行模式 hadoop一共有如下三种运行方式&#xff1a; 1. 本地运行。数据存储在linux本地&#xff0c;测试偶尔用一下。我们上一节课使用的就是本地运行模式hadoop100。 2. 伪分布式。在一台机器上模拟出 Hadoop 分布式系统的各个组件&#x…...

力扣——25 K个一组翻转链表

目录 1.题目描述&#xff1a; 2.算法分析&#xff1a; 3.代码展示&#xff1a; 1.题目描述&#xff1a; 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总…...

React Router Vs Vue Router

文章目录 前言✅ React Router vs Vue Router 对比一览&#x1f9e9; React Router 的底层原理简述① 路由声明与匹配&#xff08;基于 JSX&#xff09;② 历史模式管理③ 响应式状态处理④ 路由渲染机制&#xff08;Outlet&#xff09; ✅ 总结&#xff1a;原理是否一样&#…...

Spark中RDD算子的介绍

引言 在大数据处理领域&#xff0c;Apache Spark凭借其高效性和灵活性备受青睐。而弹性分布式数据集&#xff08;Resilient Distributed Datasets&#xff0c;简称RDD&#xff09;则是Spark的核心数据结构。RDD算子作为操作RDD的关键工具&#xff0c;掌握它们对于充分发挥Spar…...

Vivo 手机官网交互效果实现解析

在现代网页设计中&#xff0c;流畅的滚动交互和精美的视觉效果是提升用户体验的关键。本文将深入解析 Vivo 手机官网 Demo 中的一个核心交互效果 —— 基于滚轮滚动的内容展示系统。这个系统允许用户通过滚动鼠标滚轮来浏览不同的手机镜头配置信息&#xff0c;同时伴随平滑的过…...

powershell批处理——io校验

powershell批处理——io校验 在刷题时&#xff0c;时常回想&#xff0c;OJ平台是如何校验竞赛队员提交的代码的&#xff0c;OJ平台并不看代码&#xff0c;而是使用“黑盒测试”&#xff0c;用测试数据来验证。对于每题&#xff0c;都事先设定了很多组输入数据&#xff08;data…...

AI——认知建模工具:ACT-R

ACT-R&#xff08;Adaptive Control of Thought—Rational&#xff09;是一种用于模拟人类认知过程的计算架构&#xff0c;广泛应用于心理学、认知科学和人工智能研究。它通过模块化的方式模拟记忆、注意力、学习、决策等认知机制。以下是ACT-R的核心概念、安装方法、基础语法及…...

Docker 容器镜像环境的依赖导出

#工作记录 如果我们想获取 Docker 容器中已有镜像的所有的依赖包信息&#xff0c;包括其他可能的系统依赖&#xff0c;用于在其他环境&#xff08;如 WSL 或 Windows&#xff09;中重新搭建相同的运行环境。 以下是完整的步骤&#xff1a; 1. 导出 Python 依赖&#xff08;r…...

[ubuntu]fatal error: Eigen/Core: No such file or directory

确认是否安装了eigen3sudo apt-get install libeigen3-dev 解决 fatal error: Eigen/Core: No such file or directory 如果已经安装&#xff0c;但当调用 eigen 库时&#xff0c;报错&#xff1a;fatal error: Eigen/Core: No such file or directory 这是因为 eigen 库默认…...

《硬件视界》专栏介绍(持续更新ing)

名人说&#xff1a;路漫漫其修远兮&#xff0c;吾将上下而求索。 —— 屈原《离骚》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 ✨ 专栏简介&#x1f4da; 当前专栏目录&#xff08;持续更新中&#xff09;&a…...

TypeScript类型挑战-刷题

TypeScript类型挑战 vscode刷题 vscode 插件 热身题 // Test Cases import type { Equal, Expect, NotAny } from "./test-utils";type cases [Expect<NotAny<HelloWorld>>, Expect<Equal<HelloWorld, string>>];// Your Code Here …...

Java后端开发day43--IO流(三)--缓冲流转换流序列化流

&#xff08;以下内容全部来自上述课程&#xff09; 缓冲流 1. 字节缓冲流 原理&#xff1a;底层自带了长度为8192的缓冲区提高性能 1.1拷贝文件&#xff08;一次读写一个字节&#xff09; //1.创建缓冲流的对象 BufferedInputStream bis new BufferedInputStream(new Fi…...

Nginx性能调优与深度监控

一&#xff1a;Nginx性能调优 1.更改进程数和连接数 &#xff08;1&#xff09;进程数 在高并发环境中&#xff0c;需要启动更多的Nginx进程以保证快速响应&#xff0c;用以处理用户的请求&#xff0c;避免造成阻塞。使用psaux命令查看Nginx运行进程的个数。从命令执行结果可…...

【LeetCode】高频 SQL 50题 题解

目录 查询 可回收且低脂的产品 寻找用户推荐人 大的国家 文章浏览 I 无效的推文 连接 使用唯一标识码替换员工ID 产品销售分析 I 进店却未进行过交易的顾客 上升的温度 每台机器的进程平均运行时间 员工奖金 学生们参加各科测试的次数 至少有5名直接下属的经理 …...

基于Qt的app开发第六天

写在前面 博主是一个大一下的计科生&#xff0c;现在正在做C面向对象程序设计的课程设计&#xff0c;具体功能可以看本专栏的第一篇博客。 目前的进度是&#xff1a;配好MySQL驱动->设计完界面->实现各个界面的切换 这一篇博主要初步实现待办板块的功能&#xff0c;即新建…...

剑指大规模 AI 可观测,阿里云 Prometheus 2.0 应运而生

作者&#xff1a;曾庆国&#xff08;悦达&#xff09; Prometheus 大家应该非常熟悉&#xff0c;正文开始前&#xff0c;让我们一起来回顾开源 Prometheus 项目的发展史。Prometheus 最初由 SoundCloud 的工程师 Bjrn Rabehl 和 Julius Volz 于 2012 年开发。当时&#xff0c;…...

阿里云2核2g安装nexus

阿里云2核2g安装nexus # 安装 JDK 1.8 sudo yum install -y java-1.8.0-openjdk-devel# 验证安装 java -version创建运行用户 cd /opt sudo wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz sudo tar -xzf latest-unix.tar.gz sudo mv nexus-3* nexussudo us…...

eFish-SBC-RK3576工控板USB HOST接口USB3.0测试操作指南

本小节特指丝印号为J8的USB HOST接口&#xff0c;本开发板只有两个USB3.0接口&#xff0c;无USB2.0 这里接U盘测试。 在不接入任何USB外设的情况下&#xff0c;先查看/dev目录下是否存在/dev/sd*设备&#xff0c;执行命令&#xff1a; $ ls /dev/sd* 如下图所示&#xff1a; …...

嵌入式软件学习指南:从入门到进阶

嵌入式软件是物联网&#xff08;IoT&#xff09;、汽车电子、智能家居等领域的核心技术之一。它涉及硬件与软件的紧密结合&#xff0c;要求开发者不仅会写代码&#xff0c;还要理解底层硬件的工作原理。本文将带你系统了解嵌入式软件的学习路径、核心知识体系及实用资源推荐。 …...